HUST-1407 郁闷的小J

离线做法:分别处理每个编号上的各种询问和操作,接着就能用树状数组维护。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <iostream>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define lowbit(x) (x&-x)
#define maxn 123456
#define s(x) Size[x]
#define k(x) Key[x]
using namespace std;
inline int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct node{int x, y, k, type, q;} q[maxn*4];
bool cmp(node a, node b){return a.k<b.k || (a.k==b.k && a.q<b.q);}
int n, m, ans[maxn*4], Key[maxn*4], Size[maxn*4], tot;

inline void Add(int x, int k){while (x<=n) s(x)+=k, x+=lowbit(x);}
inline int Query(int x){int now=0; while (x>0) now+=s(x), x-=lowbit(x); return now;}
int main()
{
	n=read(), m=read();
	rep(i, 1, n) q[++tot]=(node){i, 1, k(i)=read(), 0, tot};
	char ch[5]; rep(i, 1, m)
	{
		scanf("%s", ch); int x=read(), y=read();
		if (ch[0]=='C') q[++tot]=(node){x, -1, k(x), 0, tot}, q[++tot]=(node){x, 1, k(x)=y, 0, tot};
		else q[++tot]=(node){x, y, read(), 1, tot};
	}
	rep(i, 1, tot) ans[i]=-1;
	sort(q+1, q+1+tot, cmp);
	int s=1; rep(t, 1, tot)
	{
		if (q[t].k==q[t+1].k) continue;
		clr(Size, 0);
		rep(i, s, t)
			if (!q[i].type) Add(q[i].x, q[i].y); else ans[q[i].q]=Query(q[i].y)-Query(q[i].x-1);
		s=t+1;
	}
	rep(i, 1, tot) if (ans[i]!=-1) printf("%d\n", ans[i]);
}
posted @ 2015-05-05 16:58  NanoApe  阅读(140)  评论(0编辑  收藏  举报
AmazingCounters.com