写的指针比较慢 自带巨大常数 在BZOJ和洛谷都tle了
卡卡常就A了
宛如智障一般在可以 直接判断大小然后swap的地方 声明了两个int来进行区间修改 于是光荣tle
没有写内存回收 删除操作直接把原来所在树上的权值设为0了 并没有删内存
#include
#include
#include
#include
using namespace std;
#define Max(_A,_B) (_A>_B?_A:_B)
#define Swap(_A,_B) (_A^=_B^=_A^=_B)
#define Min(_A,_B) (_A<_B?_A:_B)
#define Abs(_A) (_A>0?_A:(-_A))
#define ll long long
const int maxn=100007;
struct Node{
int mx,w;
Node *ls,*rs;
void pushup(){
w=mx=0;
if(ls!=NULL) {
w+=ls->w;
mx=Max(mx,ls->mx);
}
if(rs!=NULL){
w+=rs->w;
mx=Max(mx,rs->mx);
}
}
}pool[maxn<<4],*root[maxn];
Node *newNode(){
static int cnt=0;
return pool+cnt++;
}
void modify(Node* &cur,int l,int r,int x,int v){
//把x点的w改为v
if(cur==NULL) cur=newNode();
if(l==r) {
cur->w=cur->mx=v;
return;
}
int mid=(l+r)>>1;
(x<=mid)?modify(cur->ls,l,mid,x,v):modify(cur->rs,mid+1,r,x,v);
cur->pushup();
}
int queryw(Node* &cur,int l,int r,int x,int y){
if(cur==NULL) return 0;
if(x<=l&&r<=y) return cur->w;
int mid=(l+r)>>1;
if(x<=mid&&y>mid) return queryw(cur->ls,l,mid,x,y)+queryw(cur->rs,mid+1,r,x,y);
if(x<=mid) return queryw(cur->ls,l,mid,x,y);
if(y>mid) return queryw(cur->rs,mid+1,r,x,y);
}
int querymx(Node* &cur,int l,int r,int x,int y){
if(cur==NULL) return 0;
if(x<=l&&r<=y) return cur->mx;
int mid=(l+r)>>1,res=0;
if(x<=mid&&y>mid) return Max(querymx(cur->ls,l,mid,x,y),querymx(cur->rs,mid+1,r,x,y));
if(x<=mid) return querymx(cur->ls,l,mid,x,y);
if(y>mid) return querymx(cur->rs,mid+1,r,x,y);
}
/*指针实现线段树 资瓷动态开点 单点修改
区间最值查询 区间和查询*/
/*树链剖分*/
struct edge{
int v,nxt;
}e[maxn<<1];
int head[maxn],eid=0,dfl[maxn],fa[maxn],
w[maxn],c[maxn],top[maxn],siz[maxn],
son[maxn],dep[maxn],tot,n;
void insert(int u,int v){// 无向边
e[++eid].v=v;e[eid].nxt=head[u];head[u]=eid;
e[++eid].v=u;e[eid].nxt=head[v];head[v]=eid;
}
void dfs1(int u){
siz[u]=1;
int i,v;
for(i=head[u];i;i=e[i].nxt){
v=e[i].v;
if(v!=fa[u]){
dep[v]=dep[u]+1;
fa[v]=u;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int t){
dfl[u]=++tot;
top[u]=t;
if(son[u]){
int i,v;
dfs2(son[u],t);
for(i=head[u];i;i=e[i].nxt){
v=e[i].v;
if(v!=fa[u]&&v!=son[u]){
dfs2(v,v);
}
}
}
}
int lca(int x,int y){
while(top[x]^top[y]){
if(dep[top[x]]return dep[x]int solvew(int x,int y,int c){
//查询颜色为c的线段树
int res=0;
while(top[x]^top[y]){
if(dep[top[x]]1,tot,dfl[top[x]],dfl[x]);
x=fa[top[x]];
}
if(dep[x]1,tot,dfl[y],dfl[x]);
return res;
}
int solvemx(int x,int y,int c){
int res=0;
while(top[x]!=top[y]){
if(dep[top[x]]1,tot,dfl[top[x]],dfl[x]));
x=fa[top[x]];
}
if(dep[x]1,tot,dfl[y],dfl[x]));
return res;
}
int read(){
char c;int s=0;bool f=1;
while(c=getchar(),(c<'0'||c>'9')&&c!='-');
c=='-'?f=0:s=c-'0';
while(c=getchar(),(c>='0'&&c<='9'))
s=s*10+c-'0';
return s;
}
int q,u,v,i;
char str[10];
int main(){
//init();
n=read();q=read();
for(i=1;i<=n;i++){
w[i]=read();c[i]=read();
}
for(i=1;i1);
dfs2(1,1);
for(i=1;i<=n;i++){
modify(root[c[i]],1,n,dfl[i],w[i]);
}
while(q--){
scanf("%s",str);
u=read();v=read();
switch(str[1]){
case 'C':modify(root[c[u]],1,n,dfl[u],0);
c[u]=v;modify(root[c[u]],1,n,dfl[u],w[u]);
break;
//城市u的居民改C教
case 'W'://城市u的评级调整为v
w[u]=v;
modify(root[c[u]],1,n,dfl[u],w[u]);
break;
case 'S':
//查询评级总和
printf("%d\n",solvew(u,v,c[u]));
break;
default:
printf("%d\n",solvemx(u,v,c[u]));
break;
}
}
return 0;
}