您的位置:首页 > 其它

BZOJ4154 [Ipsc2015]Generating Synergy

2016-04-29 14:51 363 查看
每个点变成二维平面上一个点,横坐标dfn纵坐标dep,这样就变成了矩形染色单点查询。

正解是kdt?然而不会啊,好在内存卡的不是很紧,二维线段树动态开点就可以过了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<ctime>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<map>
using namespace std;
#define MAXN 100010
#define MAXM 27600010
#define INF 1000000000
#define MOD 1000000007
#define ll long long
#define eps 1e-8
struct vec{
int to;
int fro;
};
char ch,B[1<<10],*S=B,*TT=B;
#define getc() (S==TT&&(TT=(S=B)+fread(B,1,1<<10,stdin),S==TT)?0:*S++)
inline int read()
{
int x=0,f=1;char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
vec mp[MAXN];
int tai[MAXN],cnt;
int n,m,c;
int tot;
int son[MAXM][2],col[MAXM],vis[MAXM];
int rt[MAXN*4];
int dep[MAXN],dfn[MAXN],fa[MAXN],tim;
int siz[MAXN];
int T;
inline void be(int x,int y){
mp[++cnt].to=y;
mp[cnt].fro=tai[x];
tai[x]=cnt;
}
void ins2(int &x,int y,int z,int p){
if(!x){
x=++tot;
son[x][0]=son[x][1]=0;
vis[x]=0;
col[x]=0;
}
if(y==z){
col[x]=1;
vis[x]=T;
return ;
}
int mid=y+z>>1;
if(p<=mid){
ins2(son[x][0],y,mid,p);
}else{
ins2(son[x][1],mid+1,z,p);
}
}
void ins1(int x,int y,int z,int p1,int p2){
ins2(rt[x],1,n,p2);
if(y==z){
return ;
}
int mid=y+z>>1;
if(p1<=mid){
ins1(x<<1,y,mid,p1,p2);
}else{
ins1(x<<1|1,mid+1,z,p1,p2);
}
}
void dfs(int x){
int i,y;
dep[x]=dep[fa[x]]+1;
dfn[x]=++tim;
siz[x]=1;
ins1(1,1,n,dfn[x],dep[x]);
for(i=tai[x];i;i=mp[i].fro){
y=mp[i].to;
dfs(y);
siz[x]+=siz[y];
}
}
void change2(int x,int y,int z,int l,int r,int cv){
if(!x){
return ;
}
if(y==l&&z==r){
col[x]=cv;
vis[x]=T;
return ;
}
int mid=y+z>>1;
if(r<=mid){
change2(son[x][0],y,mid,l,r,cv);
}else if(l>mid){
change2(son[x][1],mid+1,z,l,r,cv);
}else{
change2(son[x][0],y,mid,l,mid,cv);
change2(son[x][1],mid+1,z,mid+1,r,cv);
}
}
void change1(int x,int y,int z,int l,int r,int l2,int r2,int cv){
if(y==l&&z==r){
change2(rt[x],1,n,l2,r2,cv);
return ;
}
int mid=y+z>>1;
if(r<=mid){
change1(x<<1,y,mid,l,r,l2,r2,cv);
}else if(l>mid){
change1(x<<1|1,mid+1,z,l,r,l2,r2,cv);
}else{
change1(x<<1,y,mid,l,mid,l2,r2,cv);
change1(x<<1|1,mid+1,z,mid+1,r,l2,r2,cv);
}
}
int anst,ansc;
void ask2(int x,int y,int z,int p){
if(!x){
return ;
}
if(vis[x]>anst){
ansc=col[x];
anst=vis[x];
}
if(y==z){
return ;
}
int mid=y+z>>1;
if(p<=mid){
ask2(son[x][0],y,mid,p);
}else{
ask2(son[x][1],mid+1,z,p);
}
}
void ask1(int x,int y,int z,int p1,int p2){
ask2(rt[x],1,n,p2);
if(y==z){
return ;
}
int mid=y+z>>1;
if(p1<=mid){
ask1(x<<1,y,mid,p1,p2);
}else{
ask1(x<<1|1,mid+1,z,p1,p2);
}
}
int main(){
int i,x,y,z,o;
int tmp;
//  freopen("g1.in","r",stdin);
tmp=read();
while(tmp--){
cnt=0;
tot=0;
ll ans=0;
tim=0;
memset(rt,0,sizeof(rt));
memset(tai,0,sizeof(tai));
n=read();
c=read();
m=read();
for(i=2;i<=n;i++){
x=read();
fa[i]=x;
be(x,i);
}
T=1;
dfs(1);
for(i=1;i<=m;i++){
x=read();
y=read();
o=read();
if(!o){
anst=0;
ask1(1,1,n,dfn[x],dep[x]);
ans+=(ll)((ll)i*ansc)%MOD;
ans%=MOD;
//cout<<ansc<<endl;
}else{
T++;
change1(1,1,n,dfn[x],dfn[x]+siz[x]-1,dep[x],dep[x]+y,o);
}
}
printf("%lld\n",ans);
}
return 0;
}

/*
1
4 3 7
1 2 2
3 0 0
2 1 3
3 0 0
1 0 2
2 0 0
4 1 1
4 0 0

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: