zoukankan      html  css  js  c++  java
  • bzoj4627[BeiJing2016]回转寿司

    bzoj4627[BeiJing2016]回转寿司

    题意:

    求在一个序列中和在区间[l,r]中的连续子序列的个数。序列大小≤100000,序列元素可以为负数。

    题解:

    题目要求这个:l<=sum[i]-sum[j-1]<=r,移项得sum[i]-l>=sum[j-1]>=sum[i]-r,故题目转化为求一个集合中值在某个区间的元素个数。神犇们的题解里用的都是权值线段树,然而我不知道怎么离散化,所以写了一个treap,不过由于写得不熟,又WA了好几发。注意检查有没有需要用long long的地方却没用。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <set>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define ll long long
     7 #define maxn 100010
     8 using namespace std;
     9 
    10 inline int read(){
    11     char ch=getchar(); int f=1,x=0;
    12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    13     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    14     return f*x;
    15 }
    16 ll v[maxn]; int ch[maxn][2],sz[maxn],cnt[maxn],tot,root,rnd[maxn];
    17 void update(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];}
    18 void rotate(int &x,bool c){
    19     int y=ch[x][c]; ch[x][c]=ch[y][!c]; ch[y][!c]=x; update(x); update(y); x=y;
    20 }
    21 void insert(int &x,ll val){
    22     if(!x){x=++tot; sz[x]=cnt[x]=1; v[x]=val; rnd[x]=rand(); return;}
    23     if(val==v[x]){cnt[x]++; sz[x]++; return;}
    24     if(val<v[x]){insert(ch[x][0],val); update(x); if(rnd[ch[x][0]]<rnd[x])rotate(x,0); return;}
    25     if(val>v[x]){insert(ch[x][1],val); update(x); if(rnd[ch[x][1]]<rnd[x])rotate(x,1); return;}
    26 }
    27 int query1(int x,ll val){
    28     if(!x)return 0;
    29     if(val<v[x])return sz[ch[x][1]]+cnt[x]+query1(ch[x][0],val);
    30     if(val==v[x])return sz[ch[x][1]]+cnt[x];
    31     if(val>v[x])return query1(ch[x][1],val);
    32 }
    33 int query2(int x,ll val){
    34     if(!x)return 0;
    35     if(val<v[x])return sz[ch[x][1]]+cnt[x]+query2(ch[x][0],val);
    36     if(val==v[x])return sz[ch[x][1]];
    37     if(val>v[x])return query2(ch[x][1],val);
    38 }
    39 int n; ll sm,ans,l,r;
    40 int main(){
    41     n=read(); l=read(); r=read(); insert(root,0);
    42     inc(i,1,n){
    43         ll a=read(); sm+=a; int x=query1(root,sm-r),y=query2(root,sm-l); ans+=(ll)x-y; insert(root,sm);
    44     }
    45     printf("%lld",ans); return 0;
    46 }

    20160818

  • 相关阅读:
    多线程《三》进程与线程的区别
    多线程《二》开启线程的两种方式
    多线程《一》线程理论
    多进程《七》生产者消费者模型
    多进程《六》队列
    互斥锁与join
    多进程《五》互斥锁
    多进程《四》守护进程
    再度认识未来——2.11
    开始——2.10
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5784415.html
Copyright © 2011-2022 走看看