小奇的花园

【问题描述】
小奇的花园有 n 个温室,标号为 1 到 n,温室以及以及温室间的双向道路形成一
棵树。
每个温室都种植着一种花,随着季节的变换,温室里的花的种类也在不断发生着
变化。
小奇想知道从温室 x 走到温室 y 的路径中(包括两个端点),第 t 种花出现的次数。
【输入格式】
第一行为两个整数 n,q,表示温室的数目和操作的数目。
第二行有 n 个整数 T 1 ,T 2 ...T n 其中 T i 表示温室 i 中的花的种类。接下来 n-1 行,每个两个整数 x, y,表示温室 x 和 y 之间有一条双向道路。
接下来 q 行,表示 q 个操作,分别为以下两种形式之一:
• C x t 表示在温室 x 中的花的种类变为 t。
• Q x y t 表示询问温室 x 走到温室 y 的路径中(包括两个端点),第 t 种花出现
的次数。
为了体现在线操作,输入数据中的每个操作的参数都进行了加密。记最后一次询
问的答案为 anslast(一开始设 anslast 为 0),下次读入中的 x,y,t 均需要异或上
anslast 以得到真实值,在 C/C++中异或为ˆ运算符,在 pascal 中为 xor 运算符。
【输出格式】
输出 q 行,每行一个正整数表示该次询问答案。
【样例输入】
5 8
10 20 30 40 50
1 2
1 3
3 4
3 5
Q 2 5 10
C 2 21
Q 3 4 21
C 6 22
Q 1 7 28
C 5 20
Q 2 5 20
Q 2 0 9
【样例输出】
1
2
0
3
1
【样例解释】
加密前的操作:
Q 2 5 10
C 3 20
Q 2 5 20
C 4 20
Q 3 5 30
C 5 20
Q 2 5 20Q 1 3 10
【数据范围】
对于 30%的数据,有 n <= 1000, q <= 2000。
对于 50%的数据,有 n <= 10000, q <= 20000。
对于 100%的数据,有 n <= 100000, q <= 200000,0 <= T <= 2^31。

树链剖分

对于每一种颜色建一棵线段树,动态开点

颜色用map离散,最多300000种颜色

动态开店用内存池防止内存超限

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<map>
  7 #include<queue>
  8 using namespace std;
  9 struct Node
 10 {
 11   int next,to;
 12 }edge[200001];
 13 queue<int>Q;
 14 int num,head[100001],pos,tot,cnt,dep[100001],fa[100001],size[100001],son[100001];
 15 int top[100001],dfn[100001],root[300001],t[300001],ans,c[10000001],ch[10000001][2],n,q;
 16 map<int,int>mp;
 17 void add(int u,int v)
 18 {
 19   num++;
 20   edge[num].next=head[u];
 21   head[u]=num;
 22   edge[num].to=v;
 23 }
 24 void dfs1(int x,int pa)
 25 {int i;
 26   dep[x]=dep[pa]+1;
 27   fa[x]=pa;
 28   size[x]=1;
 29   for (i=head[x];i;i=edge[i].next)
 30     {
 31       int v=edge[i].to;
 32       if (v==pa) continue;
 33       dfs1(v,x);
 34       size[x]+=size[v];
 35       if (size[v]>size[son[x]]) son[x]=v;
 36     }
 37 }
 38 void dfs2(int x,int pa,int tp)
 39 {int i;
 40   top[x]=tp;
 41   dfn[x]=++tot;
 42   if (son[x]) dfs2(son[x],x,tp);
 43   for (i=head[x];i;i=edge[i].next)
 44     {
 45       int v=edge[i].to;
 46       if (v==pa||son[x]==v) continue;
 47       dfs2(v,x,v);
 48     }
 49 }
 50 int query(int rt,int l,int r,int L,int R)
 51 {
 52   if (!rt) return 0;
 53   if (l>=L&&r<=R) return c[rt];
 54   int mid=(l+r)/2,as=0;
 55   if (L<=mid) as+=query(ch[rt][0],l,mid,L,R);
 56   if (R>mid) as+=query(ch[rt][1],mid+1,r,L,R);
 57   return as;
 58 }
 59 int ask(int x,int y,int c)
 60 {
 61   int as=0;
 62   while (top[x]!=top[y])
 63     {
 64       if (dep[top[x]]<dep[top[y]]) swap(x,y);
 65       as+=query(root[c],1,n,dfn[top[x]],dfn[x]);
 66       x=fa[top[x]];
 67     }
 68   if (dep[x]>dep[y]) swap(x,y);
 69   as+=query(root[c],1,n,dfn[x],dfn[y]);
 70   return as;
 71 }
 72 void update(int &rt,int l,int r,int x)
 73 {
 74   if (!rt)
 75     {
 76       if (Q.empty()==0) rt=Q.front(),Q.pop();
 77       else rt=++pos;
 78     }
 79   c[rt]++;
 80   if (l==r) return;
 81   int mid=(l+r)/2;
 82   if (x<=mid) update(ch[rt][0],l,mid,x);
 83   else update(ch[rt][1],mid+1,r,x);
 84 }
 85 void del(int &rt,int l,int r,int x)
 86 {
 87   c[rt]--;
 88   if (l==r&&c[rt]==0)
 89     {
 90       Q.push(rt);
 91       rt=0;
 92     }
 93   if (l==r) return;
 94   int mid=(l+r)/2;
 95   if (x<=mid) del(ch[rt][0],l,mid,x);
 96   else del(ch[rt][1],mid+1,r,x);
 97   if (c[rt]==0)
 98     {
 99       ch[rt][0]=ch[rt][1]=0;
100       Q.push(rt);
101       rt=0;
102     }
103 }
104 int main()
105 {int i,u,v,x,y,c;
106   char s[21];
107   cin>>n>>q;
108   for (i=1;i<=n;i++)
109     {
110       scanf("%d",&t[i]);
111       if (mp.count(t[i])==0) mp[t[i]]=++cnt;
112       t[i]=mp[t[i]];
113     }
114   for (i=1;i<=n-1;i++)
115     {
116       scanf("%d%d",&u,&v);
117       add(u,v);add(v,u);
118     }
119   dfs1(1,0);
120   dfs2(1,0,1);
121   for (i=1;i<=n;i++)
122     {
123       update(root[t[i]],1,n,dfn[i]);
124     }
125   ans=0;
126   while (q--)
127     {
128       scanf("%s",s);
129       if (s[0]==‘Q‘)
130     {
131       scanf("%d%d%d",&x,&y,&c);
132       x^=ans;y^=ans;c^=ans;
133       ans=0;
134       if (mp.count(c)==0)
135         {
136           printf("0\n");
137           continue;
138         }
139       c=mp[c];
140       ans=ask(x,y,c);
141       printf("%d\n",ans);
142     }
143       else
144     {
145       scanf("%d%d",&x,&c);
146       x^=ans;c^=ans;
147       del(root[t[x]],1,n,dfn[x]);
148       if (mp.count(c)==0) mp[c]=++cnt;
149       t[x]=mp[c];
150       update(root[t[x]],1,n,dfn[x]);
151     }
152     }
153 }

原文地址:https://www.cnblogs.com/Y-E-T-I/p/8653247.html

时间: 2024-09-29 00:13:50

小奇的花园的相关文章

【Luogu】U16325小奇的花园(树链剖分)

题目链接 学了学动态开点的树链剖分,其实跟动态开点的线段树差不多啦 查询的时候别ssbb地动态开点,如果没这个点果断返回0就行 只要注意花的种类能到intmax就行qwq!!!! #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<cstdlib> #include<map> #define mid ((l+r)>>

【BZOJ-4548&amp;3658】小奇的糖果&amp;Jabberwocky 双向链表 + 树状数组

4548: 小奇的糖果 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 103  Solved: 47[Submit][Status][Discuss] Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾 起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数. 接下来 T 组测试数据,对于每组测试数据,第

【NOIP模拟赛】小奇挖矿 2

[题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小奇最初在0号星球. 有n处矿体,第i处矿体有ai单位原矿,在第bi个星球上. 由于飞船使用的是老式的跳跃引擎,每次它只能从第x号星球移动到第x+4号星球或x+7号星球.每到一个星球,小奇会采走该星球上所有的原矿,求小奇能采到的最大原矿数量. 注意,小奇不必最终到达m号星球. [输入格式] 第一行2个整数n,m

4711: 小奇挖矿

4711: 小奇挖矿 Description [题目背景] 小奇在喵星系使用了无限非概率驱动的采矿机,以至于在所有星球上都采出了一些矿石,现在它准备建一些矿石仓 库并把矿石运到各个仓库里. [问题描述] 喵星系有n个星球,标号为1到n,星球以及星球间的航线形成一棵树.所有星球间的双向航线的长度都为1.小奇要 在若干个星球建矿石仓库,设立每个仓库的费用为K.对于未设立矿石仓库的星球,设其到一个仓库的距离为i,则 将矿石运回的费用为Di.请你帮它决策最小化费用. Input 第一行2个整数n,K.

【BZOJ4548】小奇的糖果 set(链表)+树状数组

[BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数. 接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N.K,分别表示点数和颜色数. 接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 - 1) 描述点的位置,最后一个数

小奇的仓库

题目来源:hzwer [题目背景] 小奇采的矿实在太多了,它准备在喵星系建个矿石仓库.令它无语的是,喵星系的货运飞船引擎还停留在上元时代! [问题描述] 喵星系有n个星球,星球以及星球间的航线形成一棵树. 从星球a到星球b要花费[dis(a,b) Xor M]秒.(dis(a,b)表示ab间的航线长度,Xor为位运算中的异或) 为了给仓库选址,小奇想知道,星球i(1<=i<=n)到其它所有星球花费的时间之和. [输入格式] 第一行包含两个正整数n,M.接下来n-1行,每行3个正整数a,b,c,

[BZOJ4548]小奇的糖果

[BZOJ4548]小奇的糖果 试题描述 有 \(N\) 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. 输入 包含多组测试数据,第一行输入一个正整数 \(T\) 表示测试数据组数. 接下来 \(T\) 组测试数据,对于每组测试数据,第一行输入两个正整数 \(N\).\(K\),分别表示点数和颜色数. 接下来 \(N\) 行,每行描述一个点,前两个数 \(x, y (|x|, |y| \le 2^{3

【OJ2216】小奇的数列

2216 -- 小奇的数列(Solution) 题目大意 : 给定一个长度为?\(n\)?的数列,以及?\(m\)?次询问,每次给出三个数?\(l\),\(r\)?和?\(P\),询问 \((\sum_{i=l_1}^{r_1}a_i)\;mod\;P\)?的最小值. 其中 \(l \le l_1 \le r_1 \le r\) . \((n\le 5\times 10^5, m\le 10^4,P\le 500)\) Tag: 抽屉原理.STL Analysis By LC: 最朴素的做法当然

小奇的矩阵(动态规划

[题目 背景] 小奇总是在数学课上思考奇怪的问题. [问题描述] 给定一个 n*m 的矩阵, 矩阵中的每个元素 aij 为正整数. 接下来规定 1. 合法的路径初始从矩阵左上角出发, 每次只能向右或向下走, 终点为右下 角. 2. 路径经过的 n+m-1 个格子中的元素为 A1, A2…A(n+m-1) , Aavg 为 Ai 的平 均数, 路径的 V 值为(n+m-1) *∑ (Ai-Aavg) ^2 (1<=i<=n+m-1) 求 V 值最小的合法路径, 输出 V 值即可, 有多组测试数据