BZOJ3307: 雨天的尾巴
3307: 雨天的尾巴
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 130 Solved: 65
[Submit][Status]
Description
N个点,形成一个树状结构。有M次发放,每次选择两个点x,y
对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
所有发放后,每个点存放最多的是哪种物品。
Input
第一行数字N,M
接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题
Output
输出有N行
每i行的数字表示第i个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0
Sample Input
5 3
1 2
3 1
3 4
5 4
2 3 3
1 5 2
3 3 3
Sample Output
2
3
3
0
2
1<=N,M<=100000
1<=a,b,x,y<=N
1<=z<=10^9
3
3
0
2
1<=N,M<=100000
1<=a,b,x,y<=N
1<=z<=10^9
HINT
Source
题目:
最近老是逗逼。。。
考虑在如果是序列上的情况,那么我们直接加是不行的,我们类似于差分,可以在x上标记一个z+1的标志,在y上标记一个z-1的标志,最后把数列从头扫一遍,用一个线段树查询最大值即可。
现在在树上,我们只要树链剖分了之后做标记,最后扫描每条重链即可。
代码:
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 250000+5 26 27 #define maxm 2500000+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 mod 1000000007 44 45 using namespace std; 46 47 inline int read() 48 49 { 50 51 int x=0,f=1;char ch=getchar(); 52 53 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 54 55 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 56 57 return x*f; 58 59 } 60 int n,m,q,tot[2],head[maxn][2],top[maxn],id[maxn],son[maxn],dep[maxn],s[maxn],fa[maxn],ans[maxn]; 61 int a[maxn]; 62 struct edge{int go,next,ch;}e[maxm][2]; 63 struct seg{int l,r,mx[2];}t[4*maxn]; 64 map<int,int>mp; 65 inline void ins(int k,int x,int y,int z) 66 { 67 e[++tot[k]][k]=(edge){y,head[x][k],z};head[x][k]=tot[k]; 68 } 69 inline void insert(int k,int x,int y,int z) 70 { 71 ins(k,x,y,z);ins(k,y,x,z); 72 } 73 inline void dfs(int x) 74 { 75 s[x]=1; 76 for(int i=head[x][0],y;i;i=e[i][0].next) 77 if(!dep[y=e[i][0].go]) 78 { 79 dep[y]=dep[x]+1;fa[y]=x; 80 dfs(y); 81 s[x]+=s[y]; 82 if(s[y]>s[son[x]])son[x]=y; 83 } 84 } 85 inline void dfs2(int x,int chain) 86 { 87 id[x]=++m;top[x]=chain; 88 if(son[x])dfs2(son[x],chain); 89 for(int i=head[x][0];i;i=e[i][0].next)if(e[i][0].go!=son[x]&&e[i][0].go!=fa[x])dfs2(e[i][0].go,e[i][0].go); 90 } 91 inline void pushup(int k) 92 { 93 int l=k<<1,r=k<<1|1; 94 t[k].mx[0]=-1; 95 if(t[l].mx[0]>t[k].mx[0]||(t[l].mx[0]==t[k].mx[0]&&a[t[l].mx[1]]<a[t[k].mx[1]]))t[k].mx[0]=t[l].mx[0],t[k].mx[1]=t[l].mx[1]; 96 if(t[r].mx[0]>t[k].mx[0]||(t[r].mx[0]==t[k].mx[0]&&a[t[r].mx[1]]<a[t[k].mx[1]]))t[k].mx[0]=t[r].mx[0],t[k].mx[1]=t[r].mx[1]; 97 } 98 inline void build(int k,int l,int r) 99 { 100 t[k].l=l;t[k].r=r;int mid=(l+r)>>1; 101 if(l==r){t[k].mx[0]=0;t[k].mx[1]=l;return;} 102 build(k<<1,l,mid);build(k<<1|1,mid+1,r); 103 } 104 inline void add(int k,int x,int y) 105 { 106 int l=t[k].l,r=t[k].r,mid=(l+r)>>1; 107 if(l==r){t[k].mx[0]+=y;return;} 108 if(x<=mid)add(k<<1,x,y);else add(k<<1|1,x,y); 109 pushup(k); 110 } 111 inline void dfs3(int x) 112 { 113 for(int i=head[x][1];i;i=e[i][1].next) 114 if(e[i][1].ch==1)add(1,e[i][1].go,1); 115 ans[x]=t[1].mx[0]?t[1].mx[1]:0; 116 for(int i=head[x][1];i;i=e[i][1].next) 117 if(e[i][1].ch==-1)add(1,e[i][1].go,-1); 118 if(son[x])dfs3(son[x]); 119 } 120 121 int main() 122 123 { 124 125 freopen("input.txt","r",stdin); 126 127 freopen("output.txt","w",stdout); 128 129 n=read();q=read(); 130 for1(i,n-1)insert(0,read(),read(),0); 131 dep[1]=1;dfs(1);dfs2(1,1); 132 int cnt=0; 133 for1(i,q) 134 { 135 int x=read(),y=read(),z=read(),t=mp[z]; 136 if(t)z=t;else mp[z]=++cnt,a[cnt]=z,z=cnt; 137 while(top[x]!=top[y]) 138 { 139 if(dep[top[x]]<dep[top[y]])swap(x,y); 140 ins(1,top[x],z,1); 141 ins(1,x,z,-1); 142 x=fa[top[x]]; 143 } 144 if(dep[x]>dep[y])swap(x,y); 145 ins(1,x,z,1); 146 ins(1,y,z,-1); 147 } 148 build(1,1,cnt); 149 for1(i,n)if(top[i]==i)dfs3(i); 150 for1(i,n)printf("%d\n",a[ans[i]]); 151 152 return 0; 153 154 }
无解的情况WA了好久。。。结果对拍了一组数据就看出问题了。。。