bzoj3052糖果公园
来源:互联网 发布:pci e视频采集卡 编程 编辑:程序博客网 时间:2024/04/28 08:50
树上修改莫队算法
非常好的一道题,其实应该把部分分都写一次
前30分是送的
50分是最普通的莫队算法
70分是clj的选择,也就是树上不修改莫队
100分是树上修改莫队
其实我昨天晚上睡觉的时候意识到第二天要很早起来写糖果公园但是还是没有意识到这个题的恶心之处,第一次写完貌似有9k。。。
然后赶紧缩,最后好不容易到了7k左右,不记得了。。。
很经典很神的算法,只不过因为程序太长了所以我不得不采用和标程对拍中间结果的办法来检查程序,如果这是在考场上那么我会毫不犹豫的选择哪个50分
不得不说艾神的题很复杂,而且我也看了vfk的题解。。。。
就这么多吧,似乎看了题解的人没资格讲做法,具体的去看vfk
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#define Size (int)pow(n,2.0/3)#define MAX 200010#define ll long longusing namespace std;int n,m,k,ind,BlockSize=0;int cnt[MAX],pos[MAX];int deep[MAX];ll ans;bool vis[MAX]={0};int father[MAX],f[MAX][20];int logg[MAX];int wait[MAX],waitting=0;ll val1[MAX],val2[MAX];vector<int>candy[MAX];vector<int>edge[MAX];vector<int>::iterator now[MAX];struct wbysr_change{int a,b;}op[MAX];struct wbysr{int l,r,id;ll ans;}ask[MAX];void debug_(){for(int i=1;i<=n;i++){printf("----%d\n",i);for(int j=0;j<edge[i].size();j++)printf("%d ",edge[i][j]);printf("\n");for(int j=0;j<candy[i].size();j++)printf("%d ",candy[i][j]);printf("\n");}//printf("debug done\n");for(int i=1;i<=n;i++)printf("%d %d\n",i,pos[i]);}int dfs(int x){//printf("fuck %d\n",x);int sum=0;/*for(int i=0;i<edge[x].size();i++)if(!deep[i]){father[i]=x;deep[i]=deep[x]+1;f[i][0]=x;for(int j=1;j<=18;j++)f[i][j]=f[f[i][j-1]][j-1];sum+=dfs(i);if(sum>=Size){BlockSize++;while(sum--)pos[wait[waitting--]]=BlockSize;sum=0;}}*////*for(vector<int>::iterator i=edge[x].begin();i!=edge[x].end();i++)if(0==deep[*i]){father[*i]=x;deep[*i]=deep[x]+1;f[*i][0]=x;for(int j=1;j<=18;j++)f[*i][j]=f[f[*i][j-1]][j-1];sum+=dfs(*i);if(sum>=Size){BlockSize++;while(sum--)pos[wait[waitting--]]=BlockSize;//printf("ooooooooooo%d %d\n",wait[waitting+1],pos[wait[waitting+1]]);sum=0;}}//*/wait[++waitting]=x;return ++sum;}bool sort_ask(wbysr a1,wbysr a2){if(pos[a1.l]!=pos[a2.l])return pos[a1.l]<pos[a2.l];elseif(pos[a1.r]!=pos[a2.r])return pos[a1.r]<pos[a2.r];return a1.id<a2.id;}void init(){scanf("%d%d%d",&n,&m,&k);//readfor(int i=1;i<=m;i++)scanf("%lld",&val1[i]);for(int i=1;i<=n;i++)scanf("%lld",&val2[i]);for(int i=1,a1,a2;i<=n-1;i++){scanf("%d%d",&a1,&a2);edge[a1].push_back(a2);edge[a2].push_back(a1);}for(int i=1,w;i<=n;i++){scanf("%d",&w);candy[i].push_back(w);}ind=0;for(int i=1,c;i<=k;i++){scanf("%d",&c);if(0==c){scanf("%d%d",&op[i].a,&op[i].b);candy[op[i].a].push_back(op[i].b);}else{ind++;scanf("%d%d",&ask[ind].l,&ask[ind].r);ask[ind].id=i;//printf("====================%d %d\n",ask[ind].l,ask[ind].r);}}//printf("sfddddddddd\n");//before donefor(int i=1;i<=n;i++)now[i]=candy[i].begin();deep[1]=1;dfs(1);//printf("888888888888888888888\n");//while(waitting)//pos[wait[waitting--]]=BlockSize;for(int i=2;i<=n;i++)logg[i]=logg[i-1]+(i==(i&-i));//for(int i=1;i<=ind;i++)//if(pos[ask[i].l]>pos[ask[i].r])//swap(ask[i].l,ask[i].r);sort(ask+1,ask+1+ind,sort_ask);//debug();//for(int i=1;i<=ind;i++)//printf("++++++++++++++++++%d %d\n",ask[i].l,ask[i].r);}void xor_point(int x){if(vis[x]){int c=*now[x];ans-=val1[c]*val2[cnt[c]];cnt[c]--;vis[x]=0;//ans+=val1[c]*val2[cnt[c]];}else{int c=*now[x];cnt[c]++;ans+=val1[c]*val2[cnt[c]];vis[x]=1;//ans-=val1[c]*val2[cnt[c]];}return;}void xor_path(int a,int b){if(deep[a]<deep[b])swap(a,b);while(deep[a]!=deep[b]){xor_point(a);a=father[a];}while(a!=b){xor_point(a);xor_point(b);a=father[a];b=father[b];}}int LCA(int a,int b){//printf("LCA begin\n");if(deep[a]<deep[b])swap(a,b);for(int i=logg[deep[a]];i>=0;i--)if(deep[f[a][i]]>=deep[b])a=f[a][i];if(a==b)return a;for(int i=logg[deep[a]];i>=0;i--)if(f[a][i]!=f[b][i]){a=f[a][i];b=f[b][i];}//printf("LCA end\n");return father[a];}ll work(int a,int b){int lca=LCA(a,b);//printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^%d %d %d\n",a,b,lca);xor_point(lca);ll tot=ans;//printf("%lld\n",tot);xor_point(lca);return tot;}void captail_mo(){for(int i=1,l=1,r=1,time=0;i<=ind;i++){//printf("%d %d %d %d %d\n",ask[i].id,ask[i].l,ask[i].r,l,r);while(time<ask[i].id){int p=op[++time].a;if(!p)continue;bool flag=vis[p];if(flag)xor_point(p);++now[p];if(flag)xor_point(p);}while(time>ask[i].id){int p=op[time--].a;if(!p)continue;bool flag=vis[p];if(flag)xor_point(p);now[p]--;if(flag)xor_point(p);}xor_path(l,ask[i].l);xor_path(r,ask[i].r);l=ask[i].l;r=ask[i].r;//printf("MO\n");ask[i].ans=work(l,r);}}bool cmp_end(wbysr a1,wbysr a2){return a1.id<a2.id;}void print(){sort(ask+1,ask+1+ind,cmp_end);for(int i=1;i<=ind;i++)printf("%lld\n",ask[i].ans);return;}void da(){for(int i=1;i<=k;i++)if(ask[i].l>ask[i].r)swap(ask[i].l,ask[i].r);return;}int main(){init();//printf("------------------init\n");//da();captail_mo();//printf("------------------captail_mo");print();return 0;}
0 0
- bzoj3052糖果公园
- bzoj3052: [wc2013]糖果公园
- BZOJ3052: [wc2013]糖果公园
- [bzoj3052][WC2013]糖果公园
- BZOJ3052 [wc2013]糖果公园
- BZOJ3052: [wc2013]糖果公园
- BZOJ3052: [wc2013]糖果公园
- BZOJ3052——糖果公园
- 【bzoj3052】糖果公园 树上莫队
- bzoj3052糖果公园 树上莫队
- [树上带修莫队] BZOJ3052: [WC2013]糖果公园
- bzoj3052&uoj58 糖果公园 带修树上莫队
- [BZOJ3052][wc2013]糖果公园(树上带修改莫队)
- bzoj3052 [wc2013]糖果公园(树上莫队,带修改)
- bzoj3052 [wc2013]糖果公园 (树上带修改莫队)
- 糖果公园
- [wc2013]糖果公园
- bzoj-3052 糖果公园
- 嵌套类,内部类,匿名内部类的定义和使用方法
- 储存一个学生的信息
- 函数中的传指针
- unity3d任意图片截取和裁剪
- hdu 3746——Cyclic Nacklace
- bzoj3052糖果公园
- java继承,多态方面的一个问题,定义一个父类对象,用子类new
- 正则过滤字符串中的数字
- Flash Player For Android
- 枯树洒落的泪花,心却不知飞向何
- SVG画菱形
- 《深入理解计算机系统》- 学习笔记 - 第二章
- 定义类
- android 各种控件颜色值的设置(使用Drawable,Color)