35分TLE求助
查看原帖
35分TLE求助
740607
Fzrcy楼主2023/6/10 20:27
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=5e5+11;
struct node{
    int x,y;
};
struct Node{node s;int ch[2],x[2],y[2],sz; ll sum,tag,val;};
struct op{int opt,x,y,z;};
int n,fa[N],m,dfn[N],dfnt,root;
vector<int>e[N];
op opt[N];
node a[N];
Node t[N];
int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void dfs(int u){
    if(u<=n){dfn[u]=++dfnt;return;}
    for(int v:e[u])dfs(v);
}
int bc;
bool cmp1(node x,node y){return x.x<y.x;}
bool cmp2(node x,node y){return x.y<y.y;}
void cmin(int &x,int y){x=x<y?x:y;}
void cmax(int &x,int y){x=x>y?x:y;}
void cmin(ll &x,ll y){x=x<y?x:y;}
void cmax(ll &x,ll y){x=x>y?x:y;}
void up(int k){
    t[k].sz=1+t[t[k].ch[0]].sz+t[t[k].ch[1]].sz;
    t[k].sum=t[t[k].ch[0]].sum+t[t[k].ch[1]].sum+t[k].val;
    t[k].x[0]=t[k].x[1]=t[k].s.x;
    t[k].y[0]=t[k].y[1]=t[k].s.y;
    if(t[k].ch[0]){
        cmin(t[k].x[0],t[t[k].ch[0]].x[0]);
        cmin(t[k].y[0],t[t[k].ch[0]].y[0]);
        cmax(t[k].x[1],t[t[k].ch[0]].x[1]);
        cmax(t[k].y[1],t[t[k].ch[0]].y[1]);
    }
    if(t[k].ch[1]){
        cmin(t[k].x[0],t[t[k].ch[1]].x[0]);
        cmin(t[k].y[0],t[t[k].ch[1]].y[0]);
        cmax(t[k].x[1],t[t[k].ch[1]].x[1]);
        cmax(t[k].y[1],t[t[k].ch[1]].y[1]);
    }
}
void Tag(int x,ll v){
    t[x].sum+=t[x].sz*v;
    t[x].tag+=v;
    t[x].val+=v;
}
void down(int x){
    if(!t[x].tag)return;
    if(t[x].ch[0])Tag(t[x].ch[0],t[x].tag);
    if(t[x].ch[1])Tag(t[x].ch[1],t[x].tag);
    t[x].tag=0;
}
int build(int l,int r,int dep){
    if(l>r)return 0;
    int k=++bc,mid=l+r>>1;
    nth_element(a+l,a+mid,a+r+1,dep?cmp1:cmp2);
    t[k].s=a[mid];
    t[k].ch[0]=build(l,mid-1,dep^1);
    t[k].ch[1]=build(mid+1,r,dep^1);
//    if(t[k].ch[0])print(t[k].s,t[t[k].ch[0]].s);
//    if(t[k].ch[1])print(t[k].s,t[t[k].ch[1]].s);
    up(k);
//    printf("%d %d %d %d %d\n",t[k].x[0],t[k].x[1],t[k].y[0],t[k].y[1],t[k].sz);
    return k;
}
void add(int k,int dep,int x1,int x2,int y1,int y2,ll val){
    if(!k)return;
    if(t[k].x[1]<x1||t[k].x[0]>x2||t[k].y[0]>y2||t[k].y[1]<y1)return;
    if(t[k].x[0]>=x1&&t[k].x[1]<=x2&&t[k].y[0]>=y1&&t[k].y[1]<=y2)return Tag(k,val);
    if(t[k].s.x>=x1&&t[k].s.x<=x2&&t[k].s.y>=y1&&t[k].s.y<=y2)t[k].val+=val;
    down(k);
    add(t[k].ch[0],dep^1,x1,x2,y1,y2,val);
    add(t[k].ch[1],dep^1,x1,x2,y1,y2,val);
    up(k);
}
ll ask(int k,int dep,int x1,int x2,int y1,int y2){
    if(!k)return 0;
    if(t[k].x[1]<x1||t[k].x[0]>x2||t[k].y[0]>y2||t[k].y[1]<y1)return 0;
    if(t[k].x[0]>=x1&&t[k].x[1]<=x2&&t[k].y[0]>=y1&&t[k].y[1]<=y2)return t[k].sum;
    down(k);
    ll ans=(t[k].s.x>=x1&&t[k].s.x<=x2&&t[k].s.y>=y1&&t[k].s.y<=y2)*t[k].val;
    ans+=ask(t[k].ch[0],dep^1,x1,x2,y1,y2);
    ans+=ask(t[k].ch[1],dep^1,x1,x2,y1,y2);
    return ans;
}
ll L[N],R[N],du[N];
void merge(int x,int y){
    x=find(x),y=find(y); if(x==y)return;
    fa[x]=y,cmin(L[y],L[x]),cmax(R[y],R[x]);
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    int now=n;
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++){
        cin>>opt[i].opt>>opt[i].x;
        if(opt[i].opt<=2)cin>>opt[i].y;
        if(opt[i].opt==2)cin>>opt[i].z;
        if(opt[i].opt==1){
            int x=find(opt[i].x),y=find(opt[i].y),z=++now;
            e[z].push_back(x),e[z].push_back(y),fa[x]=fa[y]=fa[z]=z;
            du[x]=du[y]=1;
        }
    }
    for(int i=1;i<=now;i++)if(du[i]==0)dfs(i);
    for(int i=1;i<=n;i++)a[i]={i,dfn[i]};
    root=build(1,n,1);
    for(int i=1;i<=n;i++)fa[i]=i,L[i]=R[i]=dfn[i];
    for(int i=1;i<=m;i++){
        if(opt[i].opt==1)merge(opt[i].x,opt[i].y);
        if(opt[i].opt==2)add(root,1,opt[i].x,opt[i].y,1,n,opt[i].z);
        if(opt[i].opt==3)cout<<ask(root,1,1,n,L[find(opt[i].x)],R[find(opt[i].x)])<<'\n';
    }
    return 0;
}
2023/6/10 20:27
加载中...