码迷,mamicode.com
首页 > 其他好文 > 详细

Contest1692 - 2019寒假集训第三十一场 UPC 11075 Problem D 小P的国际象棋

时间:2019-02-23 00:57:08      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:pre   date   contest   long   国际   pac   简单的   区间修改   inner   

  非常简单的单点修改+区间加+区间查询。我用的是最近刚学的区间修改版本树状数组。
  直接维护即可,注意修改后的单点值已经不是a[i],或者b[i],要通过区间查询求单点。不然是错的。

  区间修改版本树状数组:

 

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#define LL long long
using namespace std;
LL c_p[400005];
LL sum_p[400005];
LL c_y[400005];
LL sum_y[400005];
LL a[200005];
LL b[200005];
int n,m;
int cnt1;
int cnt2;
int lowbit(int x){
  return x&(-x);
}
void update(int x,int w,LL c[],LL sum[]){
  for (int i=x;i<=n;i+=lowbit(i)){
     c[i]+=(LL)w;
     sum[i]+=(LL)w*(x-1);
  }
}
LL sum(int x,LL c[],LL sum[]){
   LL ans=0;
   for (int i=x;i>0;i-=lowbit(i)){
    ans+=(LL)x*c[i]-sum[i];
   }
   return ans;
}
int main(){
 
  while(~scanf("%d%d",&n,&m)){
     a[0]=0;
     cnt1=0;
     cnt2=0;
     for (int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        update(i,a[i]-a[i-1],c_p,sum_p);
     }
     b[0]=0;
     for (int i=1;i<=n;i++){
        scanf("%lld",&b[i]);
        update(i,b[i]-b[i-1],c_y,sum_y);
     }
     int ss=0;
     while(m--){
        ss++;
        char op[10];
        char to;
        int x,y,w;
        scanf("%s",op);
        if (op[1]==i){
            scanf(" %c",&to);
            scanf("%d%d",&x,&y);
            if (to==P){
                int lw=sum(x,c_p,sum_p)-sum(x-1,c_p,sum_p);
                int rw=sum(y,c_p,sum_p)-sum(y-1,c_p,sum_p);
                update(x,rw-lw,c_p,sum_p);
                update(x+1,lw-rw,c_p,sum_p);
                update(y,lw-rw,c_p,sum_p);
                update(y+1,rw-lw,c_p,sum_p);
            }else {
                int lw=sum(x,c_y,sum_y)-sum(x-1,c_y,sum_y);
                int rw=sum(y,c_y,sum_y)-sum(y-1,c_y,sum_y);
                update(x,rw-lw,c_y,sum_y);
                update(x+1,lw-rw,c_y,sum_y);
                update(y,lw-rw,c_y,sum_y);
                update(y+1,rw-lw,c_y,sum_y);
            }
        }
        else if (op[1]==u){
            scanf(" %c",&to);
            int l,r;
            scanf("%d%d%d",&l,&r,&w);
            if (to==P){
                update(l,w,c_p,sum_p);
                update(r+1,-w,c_p,sum_p);
            }else {
                update(l,w,c_y,sum_y);
                update(r+1,-w,c_y,sum_y);
            }
        }else if (op[1]==t){
            scanf(" %c",&to);
            scanf("%d%d",&x,&y);
            if (to==P){
                w=sum(x,c_y,sum_y)-sum(x-1,c_y,sum_y);
                update(x,-w,c_y,sum_y);
                update(x+1,w,c_y,sum_y);
                update(y,w,c_p,sum_p);
                update(y+1,-w,c_p,sum_p);
            }else {
                w=sum(x,c_p,sum_p)-sum(x-1,c_p,sum_p);
                update(x,-w,c_p,sum_p);
                update(x+1,w,c_p,sum_p);
                update(y,w,c_y,sum_y);
                update(y+1,-w,c_y,sum_y);
            }
        }else {
           int l,r;
           scanf("%d%d",&l,&r);
           LL num_p=sum(r,c_p,sum_p)-sum(l-1,c_p,sum_p);
           LL num_y=sum(r,c_y,sum_y)-sum(l-1,c_y,sum_y);
           if (num_p>num_y){
             cnt1++;
             printf("P %lld\n",num_p);
           }else {
             cnt2++;
             printf("Y %lld\n",num_y);
           }
        }
     }
     if (cnt1>cnt2){
        printf("little P is winner!\n");
     }else if (cnt1<cnt2){
        printf("little Y is winner!\n");
     }else {
        printf("five five open\n");
     }
  }
  return 0;
}

 

 

 

留坑 :线段树版本:

 

Contest1692 - 2019寒假集训第三十一场 UPC 11075 Problem D 小P的国际象棋

标签:pre   date   contest   long   国际   pac   简单的   区间修改   inner   

原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10421243.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!