• loj2062 [HAOI2016]地图


    ref

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int n, m, q, a[100005], uu, vv, hea[100005], cnt, dfn[100005], loo[100005];
    int idx, dui[100005], qwq[100005], siz[100005], ans[100005], blc1, blc2;
    int bei[100005], jis[1000005], qaq[2][1005], ovo[100005];
    struct Edge{
    	int too, nxt, val;
    }edge[300005];
    struct Node{
    	int ll, rr, id, ty, li;
    }nd[100005];
    void add_edge(int fro, int too){
    	edge[++cnt].nxt = hea[fro];
    	edge[cnt].too = too;
    	hea[fro] = cnt;
    }
    bool cmp(Node x, Node y){
    	if(bei[x.ll]!=bei[y.ll])	return bei[x.ll]<bei[y.ll];
    	if(bei[x.ll]&1)	return x.rr<y.rr;
    	else	return x.rr>y.rr;
    }
    void dfs1(int x, int f){
    	dfn[x] = loo[x] = ++idx;
    	dui[idx] = x;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(t==f)	continue;
    		if(!dfn[t]){
    			dfs1(t, x);
    			loo[x] = min(loo[x], loo[t]);
    		}
    		else	loo[x] = min(loo[x], dfn[t]);
    	}
    }
    void dfs2(int x){
    	qwq[x] = ++idx;
    	siz[x] = 1;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(!qwq[t] && loo[t]>=dfn[x]){
    			dfs2(t);
    			siz[x] += siz[t];
    		}
    	}
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(!qwq[t] && loo[t]<dfn[x]){
    			dfs2(t);
    			siz[dui[loo[t]]] += siz[t];
    		}
    	}
    }
    void add(int x){
    	int p=(x-1)/blc2+1;
    	if(jis[x]&1)	qaq[1][p]--, qaq[0][p]++;
    	else if(jis[x])	qaq[0][p]--, qaq[1][p]++;
    	else	qaq[1][p]++;
    	jis[x]++;
    }
    void dec(int x){
    	int p=(x-1)/blc2+1;
    	if(jis[x]==1)	qaq[1][p]--;
    	else if(jis[x]&1)	qaq[1][p]--, qaq[0][p]++;
    	else	qaq[0][p]--, qaq[1][p]++;
    	jis[x]--;
    }
    int main(){
    	cin>>n>>m;
    	blc1 = sqrt(n);
    	blc2 = sqrt(1000000);
    	for(int i=1; i<=n; i++){
    		scanf("%d", &a[i]);
    		bei[i] = (i - 1) / blc1 + 1;
    	}
    	for(int i=1; i<=m; i++){
    		scanf("%d %d", &uu, &vv);
    		add_edge(uu, vv);
    		add_edge(vv, uu);
    	}
    	dfs1(1, 0);
    	idx = 0;
    	dfs2(1);
    	cin>>q;
    	for(int i=1; i<=q; i++){
    		scanf("%d %d %d", &nd[i].ty, &uu, &nd[i].li);
    		nd[i].ll = qwq[uu]; nd[i].rr = qwq[uu] + siz[uu] - 1;
    		nd[i].id = i;
    	}
    	sort(nd+1, nd+1+q, cmp);
    	for(int i=1; i<=n; i++)
    		ovo[qwq[i]] = a[i];
    	int l=nd[1].ll, r=l-1;
    	for(int i=1; i<=q; i++){
    		while(l>nd[i].ll)	add(ovo[--l]);
    		while(l<nd[i].ll)	dec(ovo[l++]);
    		while(r<nd[i].rr)	add(ovo[++r]);
    		while(r>nd[i].rr)	dec(ovo[r--]);
    		int now=0, p=(nd[i].li-1)/blc2+1;
    		for(int j=1; j<p; j++)
    			now += qaq[nd[i].ty][j];
    		for(int j=blc2*(p-1)+1; j<=nd[i].li; j++)
    			if(jis[j] && (jis[j]&1)==nd[i].ty)
    				now++;
    		ans[nd[i].id] = now;
    	}
    	for(int i=1; i<=q; i++)
    		printf("%d
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    一台服务器Nginx配置多个域名(一级域名或二级)
    Nginx启动和停止
    git删除本地及远程分支
    纯js实现复制内容到剪切板
    js 实现字符串转日期进行比较大小
    git 本地分支与远程分支 新建/删除/合并
    设置Git 记住密码
    炒鸡简单的javaScript的call和apply方法
    如何打war包
    Git 查看远程分支、本地分支、删除本地分支及远程分支
  • 原文地址:https://www.cnblogs.com/poorpool/p/9003609.html
Copyright © 2020-2023  润新知