裸的树链剖分,似乎数据有点大。用线段树维护会T,加个读入挂,树状数组能怼过去。。。
似乎连树状数组都没必要了。直接用数组也可做...
#include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define BUF_SIZE 100000 bool IOerror=0; inline bool blank(char ch) { return ch==' '||ch=='\n'||ch=='\r'||ch=='\t'; } inline char nc() { static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; if (p1==pend) { p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); if (pend==p1) { IOerror=1; return -1; } //{printf("IO error!\n");system("pause");for (;;);exit(0);} } return *p1++; } inline void read(int &x) { bool sign=0; char ch=nc(); x=0; for (; blank(ch); ch=nc()); if (IOerror)return; if (ch=='-')sign=1,ch=nc(); for (; ch>='0'&&ch<='9'; ch=nc())x=x*10+ch-'0'; if (sign)x=-x; } inline void read(char *s) { char ch=nc(); for (; blank(ch); ch=nc()); if (IOerror)return; for (; !blank(ch)&&!IOerror; ch=nc())*s++=ch; *s=0; } /// typedef long long ll; const int MAXN = 100000+50; int n,m; ll ans [MAXN]; int edge_id[MAXN]; struct Edge { int to,next; } edge[MAXN*2]; int head[MAXN],tot; int top[MAXN];//top[v]表示v所在的重链的顶端节点 int fa[MAXN]; //父亲节点 int deep[MAXN];//深度 int num[MAXN];//num[v]表示以v为根的子树的节点数 int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置 int fp[MAXN];//和p数组相反 int son[MAXN];//重儿子 int pos; int out[MAXN];//dfs序 void init() { tot = 0; memset(head,-1,sizeof(head)); pos = 0; memset(son,-1,sizeof(son)); } void addedge(int u,int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son { deep[u] = d; fa[u] = pre; num[u] = 1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v != pre) { dfs1(v,u,d+1); num[u] += num[v]; if(son[u] == -1 || num[v] > num[son[u]]) son[u] = v; } } } void getpos(int u,int sp) //第二遍dfs求出top和p { top[u] = sp; p[u] = ++pos; fp[p[u]] = u; if(son[u]!=-1) getpos(son[u],sp); for(int i = head[u] ; i != -1; i = edge[i].next) { int v = edge[i].to; if(v != son[u] && v != fa[u]) getpos(v,v); } out[u]=pos; } struct TREE { ll tree[MAXN+5]; void init() { memset(tree,0,sizeof tree); } int lowbit(int x) { return x&-x; } void add(int x,int value) { for (int i=x; i<=n; i=i+lowbit(i)) { tree[i]+=value; } } ll get(int x) { ll sum=0; for (int i=x; i; i-=lowbit(i)) { sum+=tree[i]; } return sum; } void update_point(int u,int v,int z)//查询u->v链的sum { int f1=top[u],f2=top[v]; while(f1!=f2) { if (deep[f1]deep[v] ) swap(u,v); // update(1,1,pos,p[u],p[v],z); //若val(u)是u到fu的边权,则用son[u] add(p[u],z); add(p[v]+1,-z); } void update_edge(int u,int v,int z)//查询u->v链的sum { int f1=top[u],f2=top[v]; ll tmp=0; while(f1!=f2) { if (deep[f1]deep[v] ) swap(u,v); if (p[son[u]]>p[v]) return ; // update(1,1,pos,p[son[u]],p[v],z); //若val(u)是u到fu的边权,则用son[u] add(p[son[u]],z); add(p[v]+1,-z); } void get_ans( ) { for (int i=1;i<=n;i++) ans[fp[i]]=get(i); } void get_ans_edge() { for (int i=1;i<=n;i++) { int x=fp[i]; int id=edge_id[x]; ans[id]=get(i); } } }; TREE tp; struct node { int x,y,z; node () {} node(int a,int b,int c) { x=a,y=b,z=c; } }; vector a1; vector a2; int uu[MAXN]; int vv[MAXN]; int main() { // freopen("in.txt","r",stdin); int cnt=1; int t; //cin>>t; read(t); while(t--) { a1.clear(); a2.clear(); init(); // scanf("%d%d",&n,&m); read(n); read(m); int u,v; for (int i=1; i1) printf(" "); printf("%lld",ans[i]); } printf("\n"); tp.init(); for (int i=0; i1) printf(" "); printf("%lld",ans[i]); } printf("\n"); } return 0; }