zoukankan      html  css  js  c++  java
  • BZOJ 1901 Dynamic Rankings

    数据结构模版题【连这么神的题都沦为模版题了Orz

    对数离散化后树状数组套权值线段树。

    #include <cstdlib>
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #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 10009
    #define maxm 20009
    #define inf 0x7fffffff
    #define k(x) Key[x]
    #define t(x) Tree[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{node *l, *r; int sum;} *blank=new(node), *Tree[maxn], *r1[maxn], *r2[maxn];
    struct node2{int v, n;} num[maxm];
    bool cmp(node2 a, node2 b){return a.v<b.v;}
    int n, m, V, q[maxn][4], Key[maxm], ln, n1, n2, c[maxm];
    char ch[5];
    void Build(int l, int r, node*&t)
    {
    	if (t==blank) t=new(node), t->l=t->r=blank, t->sum=0;
    	if (l==r) return;
    	int mid=(l+r)>>1;
    	Build(l, mid, t->l), Build(mid+1, r, t->r);
    }
    void Add(int k, int y, int l, int r, node *u, node*&t)
    {
    	if (t==blank) t=new(node), t->l=t->r=blank, t->sum=0;
    	t->sum=u->sum+y;
    	if (l==r) return; int mid=(l+r)>>1;
    	if (k<=mid)
    		t->r=u->r, Add(k, y, l, mid, u->l, t->l);
    	else
    		t->l=u->l, Add(k, y, mid+1, r, u->r, t->r);
    }
    inline void Change(int t, int k)
    {
    	node *p; int v=k(t); k(t)=k;
    	for(int x=t; x<=n; x+=lowbit(x))
    		Add(v, -1, 1, ln, t(x), p=blank), t(x)=p;
    	for(int x=t; x<=n; x+=lowbit(x))
    		Add(k, 1, 1, ln, t(x), p=blank), t(x)=p;
    }
    inline int Query(int l, int r, int k)
    {
    	n1=n2=0; k--;
    	for(int x=l-1; x; x-=lowbit(x)) r1[++n1]=t(x);
    	for(int x=r; x; x-=lowbit(x)) r2[++n2]=t(x);
    	int L=1, R=ln;
    	while (L<R)
    	{
    		int sum=0, mid=(L+R)>>1;
    		rep(j, 1, n1) sum-=r1[j]->l->sum;
    		rep(j, 1, n2) sum+=r2[j]->l->sum;
    		if (sum<=k)
    		{
    			L=mid+1, k-=sum;
    			rep(j, 1, n1) r1[j]=r1[j]->r;
    			rep(j, 1, n2) r2[j]=r2[j]->r;
    		}
    		else
    		{
    			R=mid;
    			rep(j, 1, n1) r1[j]=r1[j]->l;
    			rep(j, 1, n2) r2[j]=r2[j]->l;
    		}
    	}
    	return c[L];
    }
    void Init(){blank->l=blank->r=blank; blank->sum=0;}
    int main()
    {
    	n=V=read(), m=read(); Init();
    	rep(i, 1, n) num[i].v=read(), num[i].n=i; 
    	rep(i, 1, m)
    	{
    		scanf("%s", ch);
    		if (ch[0]=='Q') 
    			q[i][0]=1, q[i][1]=read(), q[i][2]=read(), q[i][3]=read();
    		else
    		{
    			q[i][0]=0, q[i][1]=read(), q[i][2]=read();
    			++V, num[V].v=q[i][2], num[V].n=n+i;
    		}
    	}
    	sort(num+1, num+V+1, cmp);
    	c[++ln]=num[1].v, k(num[1].n)=1;
    	rep(i, 2, V)
    	{
    		if (num[i].v != num[i-1].v) c[++ln]=num[i].v;
    		k(num[i].n)=ln;
    	}
    	Build(1, ln, t(0)=blank);
    	rep(i, 1, n)
    	{
    		node *p=t(0);
    		rep(j, i-lowbit(i)+1, i)
    			Add(k(j), 1, 1, ln, p, t(i)=blank), p=t(i);
    	}
    	rep(i, 1, m)
    		if (!q[i][0]) Change(q[i][1], k(n+i));
    		else printf("%d
    ", Query(q[i][1], q[i][2], q[i][3]));
    	return 0;
    }
  • 相关阅读:
    LeetCode 40. 组合总和 II(Combination Sum II)
    LeetCode 129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)
    LeetCode 60. 第k个排列(Permutation Sequence)
    LeetCode 47. 全排列 II(Permutations II)
    LeetCode 46. 全排列(Permutations)
    LeetCode 93. 复原IP地址(Restore IP Addresses)
    LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)
    LeetCode 59. 螺旋矩阵 II(Spiral Matrix II)
    一重指针和二重指针
    指针的意义
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4479302.html
Copyright © 2011-2022 走看看