题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3757

题解:

颜色种数不太好用树形数据结构维护,因为子节点的信息不能快速合并为父节点的信息。而莫队算法正是解决这类题目的利器。

节点与节点间的转移可以戳vfleaking的blog:http://vfleaking.blog.163.com/blog/static/174807634201311011201627/

比较巧妙的一点是把麻烦的lca去掉,然后统计答案的时候加上,统计完了再删去。

其实我做这题是为了测试各种树分块的快慢。。。

#1 按王室联邦的分块方法,可以保证所有的块内距离<=sqrt(n),最多有一块的大小>sqrt(n)并且<3sqrt(n)。块内可能是不连通的。

    但这对我们算法的执行并没有什么影响,因为它只是作为莫队算法排序的参照(可以说是估价函数)。

    块大小sqrt(n) 耗时 8744ms

    块大小sqrt(n*log2(n)) 耗时 7520ms

  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 200000+5
 26 
 27 #define maxm 200000+5
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 44 
 45 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
 46 
 47 #define mod 1000000007
 48 
 49 using namespace std;
 50 
 51 inline int read()
 52 
 53 {
 54 
 55     int x=0,f=1;char ch=getchar();
 56 
 57     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 58 
 59     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 60 
 61     return x*f;
 62 
 63 }
 64 int n,m,size,top,cnt,tot,rt,ti,ret;
 65 int a[maxn],head[maxn],ans[maxn],s[maxn],b[maxn],pos[maxn],sta[maxn],f[maxn][18],dep[maxn];
 66 struct rec{int l,r,x,y,id;}q[maxn];
 67 struct edge{int go,next;}e[2*maxn];
 68 bool v[maxn];
 69 inline void add(int x,int y)
 70 {
 71     e[++tot]=(edge){y,head[x]};head[x]=tot;
 72     e[++tot]=(edge){x,head[y]};head[y]=tot;
 73 }
 74 inline void dfs(int x)
 75 {
 76     pos[x]=++ti;int tmp=top;
 77     for1(i,17)if(dep[x]>=1<<i)f[x][i]=f[f[x][i-1]][i-1];else break;
 78     for4(i,x)if(y!=f[x][0])
 79     {
 80         f[y][0]=x;dep[y]=dep[x]+1;
 81         dfs(y);
 82         if(top-tmp>=size)
 83         {
 84             ++cnt;
 85             while(top!=tmp)b[sta[top--]]=cnt;
 86         }
 87     }
 88     sta[++top]=x;
 89 }
 90 inline int lca(int x,int y)
 91 {
 92     if(dep[x]<dep[y])swap(x,y);
 93     int t=dep[x]-dep[y];
 94     for0(i,17)if(t&(1<<i))x=f[x][i];
 95     if(x==y)return x;
 96     for3(i,17,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
 97     return f[x][0];
 98 }
 99 inline void change(int x)
100 {
101     if(v[x]){s[a[x]]--;if(!s[a[x]])ret--;}
102     else {s[a[x]]++;if(s[a[x]]==1)ret++;}
103     v[x]^=1;
104 }
105 inline void work(int x,int y)
106 {
107     while(x!=y)
108     {
109         if(dep[x]<dep[y])swap(x,y);
110         change(x);
111         x=f[x][0];
112     }
113 }
114 inline bool cmp(rec x,rec y){return b[x.l]==b[y.l]?pos[x.r]<pos[y.r]:b[x.l]<b[y.l];}
115 
116 int main()
117 
118 {
119 
120     freopen("input.txt","r",stdin);
121 
122     freopen("output.txt","w",stdout);  
123     n=read();m=read();
124     for1(i,n)a[i]=read();
125     for1(i,n){int x=read(),y=read();add(x,y);if(x*y==0)rt=x+y;}
126     size=sqrt(n);
127     dfs(rt);
128     while(top)b[sta[top--]]=cnt;
129     for1(i,m)
130     {
131         q[i].l=read(),q[i].r=read(),q[i].x=read(),q[i].y=read(),q[i].id=i;
132         if(b[q[i].l]>b[q[i].r])swap(q[i].l,q[i].r);
133     }
134     sort(q+1,q+m+1,cmp);
135     int l=rt,r=rt;
136     for1(i,m)
137     {
138         work(l,q[i].l);work(r,q[i].r);
139         l=q[i].l;r=q[i].r;int f=lca(l,r);
140         change(f);
141         ans[q[i].id]=ret-(int)(q[i].x!=q[i].y&&s[q[i].x]&&s[q[i].y]);
142         change(f);
143     }
144     for1(i,m)printf("%d\n",ans[i]);
145 
146     return 0;
147 
148 }  
View Code

相关文章:

  • 2022-12-23
  • 2021-06-17
  • 2021-06-15
  • 2022-01-02
  • 2021-10-07
  • 2021-04-08
  • 2021-11-18
猜你喜欢
  • 2021-07-11
  • 2022-02-18
  • 2021-06-05
  • 2021-08-03
  • 2021-09-05
相关资源
相似解决方案