zoukankan      html  css  js  c++  java
  • Serega and Fun Codeforces

    https://codeforces.com/problemset/problem/455/D

    其实方法很多,然而当初一个也想不到...

    1.分块,块内用链表维护

    修改[l,r]就当成删除第r个元素,在第l个元素之前插入删掉的元素:就找到r删除,然后调整各个块的结构(对于[block[l]+1,block[r]]中的每个块,把它之前一块的最后一个元素移到自身块的第一个元素),然后找到l应该插入的位置并插入l

    修改的同时,维护一下各个块中各个元素出现的次数

    查询应该没什么问题了。。。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 using namespace std;
      6 #define fi first
      7 #define se second
      8 #define mp make_pair
      9 #define pb push_back
     10 typedef long long ll;
     11 typedef unsigned long long ull;
     12 typedef pair<int,int> pii;
     13 const int bs=300;
     14 int cnt;//块数
     15 struct E
     16 {
     17     int pre,nxt;int d;
     18 }e[100100];
     19 int he[355],ta[355];//head,tail
     20 int bl[100100],st[355],ed[355];
     21 int num[355][100100];
     22 void add_tail(int b,int x)
     23 {
     24     if(!ta[b])
     25     {
     26         he[b]=ta[b]=x;
     27     }
     28     else
     29     {
     30         e[ta[b]].nxt=x;e[x].pre=ta[b];
     31         ta[b]=x;
     32     }
     33     ++num[b][e[x].d];
     34 }
     35 int remove_tail(int b)
     36 {
     37     int t=ta[b];
     38     --num[b][e[t].d];
     39     if(he[b]==ta[b])
     40     {
     41         he[b]=ta[b]=0;
     42     }
     43     else
     44     {
     45         ta[b]=e[t].pre;
     46         e[e[t].pre].nxt=0;e[t].pre=0;
     47     }
     48     return t;
     49 }
     50 void add_head(int b,int x)
     51 {
     52     if(!he[b])
     53     {
     54         he[b]=ta[b]=x;
     55     }
     56     else
     57     {
     58         e[he[b]].pre=x;e[x].nxt=he[b];
     59         he[b]=x;
     60     }
     61     ++num[b][e[x].d];
     62 }
     63 void ins_before(int b,int x,int y)//ins x to b before y
     64 {
     65     if(!he[b])
     66     {
     67         he[b]=ta[b]=x;
     68     }
     69     else if(y==he[b])
     70     {
     71         e[y].pre=x;
     72         e[x].nxt=y;
     73         he[b]=x;
     74     }
     75     else if(!y)
     76     {
     77         e[ta[b]].nxt=x;
     78         e[x].pre=ta[b];
     79         ta[b]=x;
     80     }
     81     else
     82     {
     83         e[e[y].pre].nxt=x;
     84         e[x].pre=e[y].pre;
     85         e[y].pre=x;
     86         e[x].nxt=y;
     87     }
     88 }
     89 int qq;
     90 int n,an,lans;
     91 int main()
     92 {
     93     //freopen("/tmp/YALI(10-23)/sample/queue/queue1.in","r",stdin);
     94     //freopen("/tmp/YALI(10-23)/sample/queue/queue1.out","w",stdout);
     95     int i,j,t,l,r,x,nl,nr,nt,b,idx;
     96     scanf("%d",&n);
     97     for(i=1;i<=n;i++)
     98     {
     99         scanf("%d",&t);
    100         bl[i]=(i-1)/bs;
    101         e[i].d=t;
    102     }
    103     cnt=(n-1)/bs;
    104     for(i=0;i<cnt;i++)
    105     {
    106         st[i]=bs*i+1;
    107         ed[i]=bs*(i+1);
    108     }
    109     st[cnt]=bs*cnt+1;ed[cnt]=n;
    110     for(i=1;i<=n;i++)    add_tail(bl[i],i);
    111     scanf("%d",&qq);
    112     while(qq--)
    113     {
    114         scanf("%d",&idx);
    115         if(idx==1)
    116         {
    117             scanf("%d%d",&l,&r);
    118             l=(l+lans-1)%n+1;
    119             r=(r+lans-1)%n+1;
    120             if(l>r)    swap(l,r);
    121             /*
    122             if(bl[l]==bl[r])
    123             {
    124                 b=bl[r];
    125                 nr=he[b];
    126                 for(j=st[b]+1;j<=r;j++)
    127                     nr=e[nr].nxt;
    128 
    129             }
    130             else
    131             */
    132             {
    133                 b=bl[r];
    134                 nr=he[b];
    135                 for(j=st[b]+1;j<=r;j++)
    136                     nr=e[nr].nxt;
    137                 if(nr==he[b])    he[b]=e[nr].nxt;
    138                 else    e[e[nr].pre].nxt=e[nr].nxt;
    139                 if(nr==ta[b])    ta[b]=e[nr].pre;
    140                 else    e[e[nr].nxt].pre=e[nr].pre;
    141                 e[nr].pre=e[nr].nxt=0;
    142                 --num[b][e[nr].d];
    143                 b=bl[l];
    144                 for(j=bl[r];j>b;j--)
    145                 {
    146                     nt=remove_tail(j-1);
    147                     add_head(j,nt);
    148                 }
    149                 if(l==ed[b])
    150                 {
    151                     nl=0;
    152                 }
    153                 else
    154                 {
    155                     nl=ta[b];
    156                     for(j=ed[b]-2;j>=l;j--)
    157                         nl=e[nl].pre;
    158                 }
    159                 ins_before(b,nr,nl);
    160                 ++num[b][e[nr].d];
    161             }
    162         }
    163         else
    164         {
    165             scanf("%d%d%d",&l,&r,&x);
    166             l=(l+lans-1)%n+1;
    167             r=(r+lans-1)%n+1;
    168             x=(x+lans-1)%n+1;
    169             if(l>r)    swap(l,r);
    170             an=0;
    171             if(bl[l]==bl[r])
    172             {
    173                 b=bl[l];
    174                 nl=he[b];
    175                 for(j=st[b]+1;j<=l;j++)
    176                     nl=e[nl].nxt;
    177                 for(j=l;j<=r;j++)
    178                 {
    179                     an+=(e[nl].d==x);
    180                     nl=e[nl].nxt;
    181                 }
    182             }
    183             else
    184             {
    185                 for(j=bl[l]+1;j<=bl[r]-1;j++)
    186                     an+=num[j][x];
    187                 b=bl[r];
    188                 nr=he[b];
    189                 an+=(e[nr].d==x);
    190                 for(j=st[b]+1;j<=r;j++)
    191                 {
    192                     nr=e[nr].nxt;
    193                     an+=(e[nr].d==x);
    194                 }
    195                 b=bl[l];
    196                 nl=ta[b];
    197                 an+=(e[nl].d==x);
    198                 for(j=ed[b]-1;j>=l;j--)
    199                 {
    200                     nl=e[nl].pre;
    201                     an+=(e[nl].d==x);
    202                 }
    203             }
    204             lans=an;
    205             printf("%d
    ",an);
    206         }
    207     }
    208     return 0;
    209 }
    View Code

    2.分块,定期重构(官方题解

    跟方法1大部分一样,但是块内不用链表,直接用vector或者数组,插入/删除就暴力,同时维护各个块中各个元素出现次数,然后每sqrt(n)次重构所有块

    3.平衡树(见官方题解下面的第一条评论)

    (额外解释:为什么是n*log^2而不是n*log呢?因为所有的下标都是动态的。询问(l,r,k)时,需要在k-splay中找出有多少个点下标在[l,r]内,而每一次查询下标必须要在0-splay中查询一下(注意下标是动态的,不能直接记下下标))


    http://210.33.19.103/contest/1025/problem/3

    此题同C.queue

  • 相关阅读:
    一百二十三:CMS系统之登录功能
    一百二十二:CMS系统之页面抽离和登录页面
    一百二十一:CMS系统之注册后跳转到上一个页面
    一百二十:CMS系统之注册功能前后端逻辑
    Python基础语法习题二
    编程语言分类和Python解释器介绍
    VS Code设置中文和配置Python环境
    Windows10系统下安装python2和python3双版本
    Python下载与安装
    前端开发之jQuery位置属性和筛选方法
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9838762.html
Copyright © 2011-2022 走看看