Jewel——2010 天津赛区 J 题

来源:互联网 发布:网吧游戏平台软件 编辑:程序博客网 时间:2024/04/29 20:53

        一大清早起来 A 掉一道划分树+树状数组+离散化的题+近200行代码的题,勉强算是弥补了今晚不能做 CF 的遗憾了吧,该死的,怎么会这个时候交我回家呢?!!

        题很裸,一看就知道是划分树求区间第 k 值 + 树状数组

        给出题目连接,懒得写 html 了:http://livearchive.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=393&page=show_problem&problem=3035

        注意不要上 hdu 上看题,上面样例给出的数据不全,但是可以在上面测题

        具体怎么做的懒得讲了,直接上代码。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <queue>#include <ctime>#include <cstdlib>#include <stack>#include <map>#include <set>#include <list>#define INT_INF 0x3fffffff#define LL_INF 0x3fffffffffffffff#define EPS 1e-12#define MOD 1000000007#define PI 3.14159265358979323846#define N 100010#define E 100010using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef unsigned int Uint;typedef double DB;struct data{    int st,en;} T[4*N];int sorted[N];int val[40][N];int to_L[40][N];int sum[N];struct node{    char name[20];    int st,en,k;} op[2*N];vector<int>y;map<int,int> ihash;map<int,int> back;void make_disc(){    sort(y.begin(),y.end());    y.erase(unique(y.begin(),y.end()),y.end());    for(int i=0; i<(int)y.size(); i++)    {        ihash[y[i]]=i+1;        back[i+1]=y[i];    }}int get_sum(int *a,int pos){    int temp=0;    while(pos>0)    {        temp+=a[pos];        pos-=pos&(-pos);    }    return temp;}int get_k(int *a,int k,int L,int R){    while(L<R)    {        int mid=(L+R)>>1;        if(get_sum(a,mid)>=k) R=mid;        else L=mid+1;    }    return L;}void update(int *a,int pos,int k){    while(pos<N)    {        a[pos]+=k;        pos+=pos&(-pos);    }}void build(int v,int st,int en,int deep){    T[v].st=st;    T[v].en=en;    if(st==en) return;    int mid=(st+en)>>1;    int mid_num=sorted[mid];    int same=mid-st+1;    for(int i=st; i<=en; i++)        if(val[deep][i]<mid_num) same--;    int L=st , R=mid+1;    for(int i=st; i<=en; i++)    {        if(i==st) to_L[deep][i]=0;        else to_L[deep][i]=to_L[deep][i-1];        if(val[deep][i]<mid_num || val[deep][i]==mid_num && same>0)        {            val[deep+1][L++]=val[deep][i];            to_L[deep][i]++;            if(val[deep][i]==mid_num) same--;        }        else val[deep+1][R++]=val[deep][i];    }    build(v<<1,st,mid,deep+1);    build(v<<1|1,mid+1,en,deep+1);}int query(int v,int st,int en,int k,int deep){    if(st==en) return val[deep][st];    int s1 , s2 , b1 , b2;    if(st==T[v].st) s1=0;    else s1=to_L[deep][st-1];    s2=to_L[deep][en]-s1;    b1=(st-1-T[v].st+1)-s1;    b2=(en-st+1)-s2;    int mid=(T[v].st+T[v].en)>>1;    if(k<=s2) return query(v<<1,T[v].st+s1,T[v].st+s1+s2-1,k,deep+1);    else return query(v<<1|1,mid+1+b1,mid+1+b1+b2-1,k-s2,deep+1);}int main(){    int n,ca=0;    while(scanf("%d",&n)!=EOF)    {        y.clear();        back.clear();        ihash.clear();        int tot=0;        for(int i=1; i<=n; i++)        {            scanf("%s",op[i].name);            if(strcmp(op[i].name,"Insert")==0)            {                tot++;                scanf("%d",&val[0][tot]);                sorted[tot]=val[0][tot];                op[i].k=sorted[tot];                y.push_back(val[0][tot]);            }            if(strcmp(op[i].name,"Query_1")==0)                scanf("%d%d%d",&op[i].st,&op[i].en,&op[i].k);            if(strcmp(op[i].name,"Query_2")==0)            {                scanf("%d",&op[i].k);                y.push_back(op[i].k);            }            if(strcmp(op[i].name,"Query_3")==0)                scanf("%d",&op[i].k);        }        make_disc();        for(int i=1; i<=tot; i++)        {            int tmp=val[0][i];            val[0][i]=sorted[i]=ihash[tmp];        }        sort(sorted+1,sorted+1+tot);        build(1,1,tot,0);        memset(sum,0,sizeof(sum));        LL ans1=0 , ans2=0 , ans3=0;        for(int i=1; i<=n; i++)        {            if(strcmp(op[i].name,"Insert")==0)                update(sum,ihash[op[i].k],1);            if(strcmp(op[i].name,"Query_1")==0)                ans1+=(LL)back[query(1,op[i].st,op[i].en,op[i].k,0)];            if(strcmp(op[i].name,"Query_2")==0)                ans2+=(LL)get_sum(sum,ihash[op[i].k]);            if(strcmp(op[i].name,"Query_3")==0)                ans3+=(LL)back[get_k(sum,op[i].k,1,N-1)];        }        printf("Case %d:\n",++ca);        printf("%I64d\n%I64d\n%I64d\n",ans1,ans2,ans3);    }    return 0;}



原创粉丝点击