求助莫队 TLE
查看原帖
求助莫队 TLE
151601
Aphros楼主2020/12/29 20:46

rt,第 3 个点过不去

#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

inline int read()
{
	int x = 0; char c = getchar();
	while(c < '0' || c > '9') c = getchar();
	while(c >= '0' && c <= '9')
		x = (x<<3)+(x<<1)+c-'0', c = getchar();
	return x;
}

const int MAXN = 200010;
const int MAXM = 150010;
const int MAXA = 1000010;
//const int N = 1000000;

int n, m, q, totn;
int dfn[MAXN], cnt, siz[MAXN], rev[MAXN];

struct Tree{
	struct edge{
		int ne, to;
		edge(int Ne=0,int To=0):ne(Ne),to(To){}
	}e[MAXN];
	int fir[MAXN], num;
	inline void reset()
	{
		for(int i=1;i<=(n<<1);i++)
			fir[i] = dfn[i] = 0;
		num = cnt = 0;
	}
	inline void join(int a, int b)
	{
		e[++num] = edge(fir[a], b);
		fir[a] = num; 
	}
	void dfs(int u)
	{
		dfn[u] = ++cnt;
		rev[cnt] = u;
		siz[u] = 1;
		for(int i=fir[u];i;i=e[i].ne)
		{
			int v = e[i].to;
			dfs(v);
			siz[u] += siz[v];
		}
	}
}T;
struct Graph{
	struct edge{
		int ne, to;
		edge(int Ne=0,int To=0):ne(Ne),to(To){}
	}e[MAXM<<1];
	int fir[MAXN], num, dfn[MAXN], cnt, low[MAXN], stk[MAXN], top;
	inline void reset()
	{
		for(int i=1;i<=(n<<1);i++)
			fir[i] = dfn[i] = 0;
		top = num = cnt = 0;
	}
	inline void join(int a, int b)
	{
		e[++num] = edge(fir[a], b);
		fir[a] = num; 
	}
	void tarjan(int u)
	{
		dfn[u] = low[u] = ++cnt;
		stk[++top] = u;
		for(int i=fir[u];i;i=e[i].ne)
		{
			int v = e[i].to;
			if(!dfn[v])
			{
				tarjan(v);
				low[u] = min(low[u], low[v]);
				if(low[v] >= dfn[u])
				{
					int x = 0; ++totn;
					T.join(u, totn);
					do {
						x = stk[top--];
						T.join(totn, x);
					} while(x != v);
				}
			}
			else low[u] = min(low[u], dfn[v]);
		}
	}
}G;
struct blocks{
	int len, pos[MAXA], lp[MAXN], rp[MAXN];
	int cnt[MAXA], sum[MAXA][2];
	int nowl, nowr;
	inline void build(int N)
	{
		nowl = 1; nowr = 0;
		len = max(1, (int)sqrt(N));
		for(int i=0;i<=N;i++)
			pos[i] = i/len+1;
		for(int i=1;i<=pos[N];i++)
		{
			lp[i] = (i-1)*len;
			rp[i] = min(N, i*len-1);
		}
	}
	inline void add(int x)
	{
		if(x == -1) return;
		if(cnt[x]) --sum[pos[x]][cnt[x]&1];
		++cnt[x];
		++sum[pos[x]][cnt[x]&1];
	}
	inline void del(int x)
	{
		if(x == -1) return ;
		--sum[pos[x]][cnt[x]&1];
		--cnt[x];
		if(cnt[x]) ++sum[pos[x]][cnt[x]&1];
	}
	inline int query(int x, int tp)
	{
		int res = 0;
		for(int i=1;i<pos[x];i++)
			res += sum[i][tp];
		for(int i=lp[pos[x]];i<=x;i++)
			if(cnt[i] && (cnt[i]&1) == tp) ++res;
		return res;
	}
}B;
int pos[MAXN];
struct ques{
	int l, r, ind, x, tp;
	bool operator<(const ques&o)const{return pos[l]^pos[o.l]?pos[l]<pos[o.l]:pos[l]&1?r<o.r:r>o.r;}
}b[MAXN];
int ans[MAXN];
int a[MAXN];

int main()
{
//	freopen("map12.in","r",stdin);
//	freopen("mine.out","w",stdout);
	n = read(); m = read();
	int maxa = 0;
	for(int i=1;i<=n;i++)
		a[i] = read(), maxa = max(maxa, a[i]);
	for(int i=1;i<=m;i++)
	{
		int u, v;
		u = read(); v = read();
		G.join(u, v);
		G.join(v, u);
	}
	totn = n;
	G.tarjan(1);
	for(int i=n+1;i<=totn;i++)
		a[i] = -1;
	T.dfs(1);
	q = read();
	for(int i=1;i<=q;i++)
	{
		int u;
		b[i].tp = read(); u = read(); b[i].x = read();
		b[i].l = dfn[u];
		b[i].r = dfn[u] + siz[u] - 1;
		b[i].ind = i;
	}
	int len = sqrt(totn);
	for(int i=1;i<=totn;i++)
		pos[i] = (i-1)/len+1;
	sort(b+1, b+q+1);
	B.build(maxa);
	for(int i=1;i<=q;i++)
	{
		while(B.nowl > b[i].l) B.add(a[rev[--B.nowl]]);
		while(B.nowr < b[i].r) B.add(a[rev[++B.nowr]]);
		while(B.nowl < b[i].l) B.del(a[rev[B.nowl++]]);
		while(B.nowr > b[i].r) B.del(a[rev[B.nowr--]]);
		ans[b[i].ind] = B.query(b[i].x, b[i].tp);
	}
	for(int i=1;i<=q;i++)
		printf("%d\n",ans[i]);
	return 0;
}
2020/12/29 20:46
加载中...