• [CF1053C]Putting Boxes Together(线段树)


    http://codeforces.com/blog/entry/62013

    两个结论:

    1.一定有一个箱子不用动。

    2.不动的箱子一定是加权前缀和为S/2的那个。

    1显然,2由1易得。

    于是问题变为:求一段区间前缀和>S/2的第一个数的位置。显然先求出S/2,再线段树上二分即可,实现过程见代码。

    自定义struct比stl:pair快,注意取模和爆long long的问题。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define ls (x<<1)
     4 #define rs (ls|1)
     5 #define lson ls,L,mid
     6 #define rson rs,mid+1,R
     7 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     8 typedef long long ll;
     9 using namespace std;
    10 
    11 const int N=200010,inf=1e9,mod=1e9+7;
    12 int n,Q,x,y,a[N],w[N];
    13 struct Tr{ ll s1,s2; }v[N<<2];
    14 struct P{ ll x,y; };
    15 
    16 void upd(int x){ v[x].s1=v[ls].s1+v[rs].s1; v[x].s2=(v[ls].s2+v[rs].s2)%mod; }
    17 
    18 void build(int x,int L,int R){
    19     if (L==R){ v[x].s1=w[L]; v[x].s2=1ll*a[L]*w[L]%mod; return; }
    20     int mid=(L+R)>>1;
    21     build(lson); build(rson); upd(x);
    22 }
    23 
    24 void mdf(int x,int L,int R,int pos,int k){
    25     if (L==R){ v[x].s1=k; v[x].s2=1ll*a[pos]*k%mod; return; }
    26     int mid=(L+R)>>1;
    27     if (pos<=mid) mdf(lson,pos,k); else mdf(rson,pos,k);
    28     upd(x);
    29 }
    30 
    31 P que(int x,int L,int R,int l,int r){
    32     if (L==l && r==R) return (P){v[x].s1,v[x].s2};
    33     int mid=(L+R)>>1;
    34     if (r<=mid) return que(lson,l,r);
    35     else if (l>mid) return que(rson,l,r);
    36         else{
    37             P s1=que(lson,l,mid),s2=que(rson,mid+1,r);
    38             return (P){s1.x+s2.x,(s1.y+s2.y)%mod};
    39         }
    40 }
    41 
    42 P ask(int x,int L,int R,int l,int r,ll k){
    43     if (L==l && r==R){
    44         if (v[x].s1<=k) return (P){inf,v[x].s1};
    45         if (L==R) return (P){l,0};
    46     }
    47     int mid=(L+R)>>1;
    48     if (r<=mid) return ask(lson,l,r,k);
    49     else if (l>mid) return ask(rson,l,r,k);
    50         else{
    51             ll sm=0,res=inf;
    52             P cur=ask(lson,l,mid,k);
    53             res=min(res,cur.x); sm+=cur.y;
    54             if (res<inf) return (P){res,sm};
    55             cur=ask(rson,mid+1,r,k-sm);
    56             res=min(res,cur.x); sm+=cur.y;
    57             return (P){res,sm};
    58         }
    59 }
    60 
    61 int work(int l,int r){
    62     int k=ask(1,1,n,l,r,que(1,1,n,l,r).x/2).x;
    63     P t1=(k==l) ? (P){0,0} : que(1,1,n,l,k-1),t2=que(1,1,n,k,r);
    64     return ((a[k]*(t1.x%mod)-t1.y+t2.y-a[k]*(t2.x%mod))%mod+mod)%mod;
    65 }
    66 
    67 int main(){
    68     freopen("1058f.in","r",stdin);
    69     freopen("1058f.out","w",stdout);
    70     scanf("%d%d",&n,&Q);
    71     rep(i,1,n) scanf("%d",&a[i]),a[i]=a[i]-i;
    72     rep(i,1,n) scanf("%d",&w[i]);
    73     build(1,1,n);
    74     while (Q--){
    75         scanf("%d%d",&x,&y);
    76         if (x<0) mdf(1,1,n,-x,y); else printf("%d
    ",work(x,y));
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    C#定时执行任务
    C#判断数据库是否可连接(PING)
    Excel之导入数据
    JQuery之杂项方法$.grep()
    .Net EF 之代码生成策略
    平台与WeLink深度融合技术汇总
    Host is not allowed to connect to this MySQL
    excel中过长的数字怎么筛选重复项
    oracle 函数大全
    WinXP添加TLS1.1、TLS1.2支持
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10351581.html
Copyright © 2020-2023  润新知