CF788&789(div1&div2)

前言

789 AB比较水,但是B分情况讨论也可以锻炼严谨思维
788ABC都是码量小也不太难的小清新题,C比较令人耳目一新
788D的思路让人难以想到
788E标准的大数据结构题

CF789A Anastasia and pebbles

Description \text{Description} Description

Anastasia喜欢去公园收集石子.她有 2 2 2 个口袋,每个口袋最多装 k k k 个石子.

但她每天只去公园 1 1 1 次,而且每次同一个口袋里只装同一种石子.问要装完 n n n 种石子共要花多少天?

输入 n n n,以及每一种石子的数量 w i w_i wi. 输出上述所求答案.

1 ≤ n ≤ 100000 ; 1 ≤ k ≤ 1000000000 ; 1 ≤ w i ≤ 10000 1\le n\le 100000;1\le k\le 1000000000; 1\le w_i\le10000 1n100000;1k1000000000;1wi10000

Solution \text{Solution} Solution

求出每种石子需要几袋子装,全部加起来除以二上取整即可.

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
const double eps=1e-12;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

ll n,m,k;
ll x[N],a[N],sum[N];
ll mn,mx,ans;
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();
  for(int i=1;i<=n;i++) x[i]=read();
  for(int i=1;i<n;i++) a[i]=abs(x[i]-x[i+1])*((i&1)?1:-1);
  for(int i=1;i<n;i++){
    sum[i]=sum[i-1]+a[i];
    if(i&1) ans=max(ans,sum[i]-mn);
    else ans=max(ans,mx-sum[i]);
    mx=max(mx,sum[i]);mn=min(mn,sum[i]);
  }
  printf("%lld\n",ans);
  return 0;
}
/*

*/

CF789B Masha and geometric depression

Description \text{Description} Description

给你一个等比数列,首项为 b 1 b_1 b1,公比为 q q q.
现在Masha在黑板上从首项开始书写这个等比数列,直到数列某项的绝对值大于 l l l,给定 m m m 个整数,若该等比数列中的某项等同于这 m m m 个整数,则不会被写出.
问Masha会写出多少个数字?如果她会写出无穷多个数字,输出inf.
注意: b 1 , q b1,q b1,q 可能为 0 0 0.

Solution \text{Solution} Solution

大特判题.
特判一下公差等于 0 / 1 / − 1 0/1/-1 0/1/1,首项等于 0 0 0 的情况,其他的暴力算即可.
需要开 longlong.

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
const double eps=1e-12;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

int n,mx;
ll d,x;
map<ll,bool>mp;
int ans;
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  x=read();d=read();mx=read();n=read();
  for(int i=1;i<=n;i++) mp[read()]=1;
  if(abs(x)>mx){
    printf("0");return 0;
  }
  if(d==0){
    if(mp[0]) printf("%d",!mp[x]);
    else printf("inf");
  }
  else if(d==1){
    if(mp[x]) printf("0");
    else printf("inf");
  }
  else if(d==-1){
    if(mp[x]&&mp[-x]) printf("0");
    else printf("inf");
  }
  else if(x==0){
    if(mp[0]) printf("0");
    else printf("inf");
  }
  else{
    while(abs(x)<=mx){
      if(!mp[x]) ++ans;
      x*=d;
    }
    printf("%d\n",ans);
  }
  return 0;
}
/*

*/

CF788A Functions again

Description \text{Description} Description

定义一个函数,函数如下:
f [ l , r ] = ∑ i = l r − 1 ∣ a i − a i + 1 ∣ × ( − 1 ) i − l f[l,r]=\sum^{r-1}_{i=l}|a_i-a_{i+1}|\times (-1)^{i-l} f[l,r]=i=lr1aiai+1×(1)il. ( 1 ≤ l , r ≤ n 1\le l,r\le n 1l,rn)
∣ x ∣ |x| x 表示 x x x 的绝对值.
现在给你一个函数,请取恰当的 l , r l,r l,r 使 f f f 值最大,请输出最大的 f f f 值.
2 ≤ n ≤ 1 0 5 2\le n\le 10^5 2n105

Solution \text{Solution} Solution

先求出差分数组的绝对值 d 1... n − 1 d_{1...n-1} d1...n1.
定义:
s u m i = ∑ j = 1 i d j × ( − 1 ) j + 1 sum_i=\sum_{j=1}^i d_j\times(-1)^{j+1} sumi=j=1idj×(1)j+1
那么我们的 f l , r f_{l,r} fl,r 就可以表示为:
( − 1 ) r + 1 × ( s u m r − s u m l − 1 ) (-1)^{r+1}\times (sum_r-sum_{l-1}) (1)r+1×(sumrsuml1)
所以从前往后扫分别记录 s u m sum sum 的最大值和最小值即可.

Description \text{Description} Description

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
const double eps=1e-12;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

ll n,m,k;
ll x[N],a[N],sum[N];
ll mn,mx,ans;
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();
  for(int i=1;i<=n;i++) x[i]=read();
  for(int i=1;i<n;i++) a[i]=abs(x[i]-x[i+1])*((i&1)?1:-1);
  for(int i=1;i<n;i++){
    sum[i]=sum[i-1]+a[i];
    if(i&1) ans=max(ans,sum[i]-mn);
    else ans=max(ans,mx-sum[i]);
    mx=max(mx,sum[i]);mn=min(mn,sum[i]);
  }
  printf("%lld\n",ans);
  return 0;
}
/*

*/

CF788B Weird journey

Description \text{Description} Description

总共有 n n n 个节点, m m m 条路径,要求其中 m − 2 m-2 m2 条路径走两遍,剩下 2 2 2 条路径仅走一遍,问不同的路径总数有多少,如果仅走一遍的两条边不同则将这两条路径视为不同.
n , m ≤ 1 0 6 n,m\le10^6 n,m106

Solution \text{Solution} Solution

把每条边拆成两个一样的边,考虑欧拉回路的条件.
由于拆了边,显然每个点的度数都是偶数.
所以选择的两条边必须含有公共端点.
考虑自环如何处理.
删掉自环后该点的度数还是偶数,所以剩下的一条边随便删即可.
细节上,需要判断含有边的点必须连通.

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e6+100;
const double eps=1e-12;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

int n,m;
int du[N];
int fa[N],tag[N];
ll num;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();m=read();
  for(int i=1;i<=n;i++) fa[i]=i;
  for(int i=1;i<=m;i++){
    int x=read(),y=read();
    fa[find(x)]=find(y);
    tag[x]=tag[y]=1;
    if(x==y){
      ++num;continue;
    }
    ++du[x];++du[y];
  }
  int cnt(0);
  for(int i=1;i<=n;i++){
    cnt+=(find(i)==i&&tag[i]!=0);
  }
  if(cnt>1||m<2){
    printf("0");return 0;
  }
  ll ans(0);
  for(int i=1;i<=n;i++){
    ans+=1ll*du[i]*(du[i]-1)/2;
    //printf("i=%d du=%d ans=%lld\n",i,du[i],ans);
  }
  ans+=num*(m-num)+num*(num-1)/2;
  printf("%lld\n",ans);
  return 0;
}
/*

*/

CF788C The Great Mixing

Description \text{Description} Description

k k k 种可乐,第 i i i 瓶可乐的 CO2 浓度是 a i 1000 \frac{a_i}{1000} 1000ai,问要配置出浓度 n 1000 \frac{n}{1000} 1000n 的可乐,最少需要几瓶可乐.
无解输出 − 1 -1 1.
0 ≤ n ≤ 1000 , k ≤ 1 0 6 0\le n\le 1000,k\le10^6 0n1000,k106

Solution \text{Solution} Solution

不难想到把所以值减 n n n 然后转化为加和为 0 0 0 的问题.
我的做法是正负两边暴力背包,值域在最差的情况下是 500 × 499 500\times499 500×499.
然后就 3 × 1 0 5 3\times 10^5 3×105艹过去了…

现在讲讲 n 2 n^2 n2 的正解.
考虑 bfs.
0 0 0 开始,向外寻找.
把边界设为 1000 1000 1000 即可.
为什么这么是对的?
设答案的组合为 x 1 + x 2 + . . . x k = 0 x_1+x_2+...x_k=0 x1+x2+...xk=0.
不难发现,通过调整前后顺序,一定可以使序列 x x x 的任意一个前缀和的绝对值均不超过 1000 1000 1000,那么这个调整后的序列就可以被 bfs 搜到.
因此这样做是正确的.

Code \text{Code} Code

代码还是之前的暴力背包
bfs 不难实现,留给读者自行思考

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e6+100;
const double eps=1e-12;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

int n,k;
int a[1050],b[1050],x,y;
int o=3e5;
int w[N];
int f1[300050],f2[300050];
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();k=read();
  for(int i=1;i<=k;i++) w[i]=read();
  sort(w+1,w+1+k);
  k=unique(w+1,w+1+k)-w-1;
  for(int i=1;i<=k;i++){
    w[i]-=n;
    if(w[i]==0){
      printf("1");return 0;
    }
    else if(w[i]>0) a[++x]=w[i];
    else b[++y]=-w[i];
  }
  if(!x||!y){
    printf("-1");return 0;
  }
  memset(f1,0x3f,sizeof(f1));
  f1[0]=0;
  for(int i=1;i<=x;i++){
    int w=a[i];
    for(int j=w;j<=o;j++) f1[j]=min(f1[j],f1[j-w]+1);
  }
  memset(f2,0x3f,sizeof(f2));
  f2[0]=0;
  for(int i=1;i<=y;i++){
    int w=b[i];
    for(int j=w;j<=o;j++) f2[j]=min(f2[j],f2[j-w]+1);
  }
  int ans=2e9;
  for(int i=1;i<=o;i++) ans=min(ans,f1[i]+f2[i]);
  printf("%d\n",ans);
  return 0;
}
/*

*/

CF788D Finding lines

Description \text{Description} Description

有一个平面,上面有一些水平或竖直的直线.
你每次可以选择一个点,询问距离该点最近的直线到该点的距离.
请求出所有的直线的横/纵坐标.
总直线数不超过 1 0 4 10^4 104.
坐标范围不超过 1 0 8 10^8 108.(询问的点也不能超过该范围)

Solution \text{Solution} Solution

思路很妙的一道题.
不难想到利用 分治.
如何设计分治状态是本题的关键.
第一感似乎是设计 s o l v e ( x 1 , x 2 , y 1 , y 2 ) solve(x1,x2,y1,y2) solve(x1,x2,y1,y2) 表示寻找横坐标在 ( x 1 , x 2 ) (x1,x2) (x1,x2) 和纵坐标在 ( y 1 , y 2 ) (y1,y2) (y1,y2) 的直线,然后找到这个矩形的中点尝试.
但是这样分治的两个子结构不互相独立,左边找到的直线也会影响右边,难以处理.
别问我为什么知道难以处理
所以我们要尝试一些特别的设计.
设计 s o l v e ( l , r ) solve(l,r) solve(l,r) 表示解决坐标在 ( l , r ) (l,r) (l,r) 的直线(同时包括横纵坐标).
询问中点 ( m i d , m i d ) (mid,mid) (mid,mid) .

  1. 若距离为 0 0 0,说明有线经过该点,记录该位置并递归 s o l v e ( l , m i d − 1 ) , s o l v e ( m i d + 1 , r ) solve(l,mid-1),solve(mid+1,r) solve(l,mid1),solve(mid+1,r)
  2. 若距离为 d ≠ 0 d\ne0 d=0,递归 s o l v e ( l , m i d − d ) , s o l v e ( m i d + d , r ) solve(l,mid-d),solve(mid+d,r) solve(l,midd),solve(mid+d,r)

最后,我们需要确定步骤一中得到的位置 ( p , p ) (p,p) (p,p) 经过的是竖线还是横线,记录之前任何一次询问不在线上的点的坐标为 ( n o , n o ) (no,no) (no,no),分别询问 ( n o , p ) (no,p) (no,p) ( p , n o ) (p,no) (p,no) 即可.

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
//#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e5+100;
const double eps=1e-12;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

int n,k;
int pl[N],tot;
int no;
int X[N],xx,Y[N],yy;
int o=1e8;
int debug(0);
void solve(int l,int r){
  if(debug)  printf("solve:(%d %d)\n",l,r);
  if(l>r) return;
  int mid=(l+r)/2;  
  printf("0 %d %d\n",mid,mid);fflush(stdout);
  int d=read();
  if(d==0){
    if(debug) printf("  ok\n");
    pl[++tot]=mid;
    solve(l,mid-1);
    solve(mid+1,r);
  }
  else{
    no=mid;
    if(debug) printf("  ??\n");
    solve(l,mid-d);solve(mid+d,r);
  }
  return;
}
signed main(){
#ifndef ONLINE_JUDGE
  //freopen("a.in","r",stdin);
  //freopen("a.out","w",stdout);
#endif
  solve(-o,o);
  if(debug) printf("tot=%d no=%d\n",tot,no);
  for(int i=1;i<=tot;i++){
    int p=pl[i];
    printf("0 %d %d\n",no,p);fflush(stdout);
    if(!read()) Y[++yy]=p;    
    printf("0 %d %d\n",p,no);fflush(stdout);
    if(!read()) X[++xx]=p;
  }
  printf("1 %d %d\n",xx,yy);
  for(int i=1;i<=xx;i++) printf("%d ",X[i]);
  putchar('\n');
  for(int i=1;i<=yy;i++) printf("%d ",Y[i]);
  return 0;
}
/*

*/

CF788E New task

Description \text{Description} Description

有一个长度为 n n n 的数列 a i a_i ai,第 i i i 个数有一个零一属性 b i b_i bi,初始所有的 b b b 都为 1 1 1.
m m m 次操作,分为两种:

1   x 1 \space x 1 x :令 b x = 0 b_x=0 bx=0.
2   x 2 \space x 2 x :令 b x = 1 b_x=1 bx=1

每次操作后输出满足条件的 p 1 < p 2 < p 3 < p 4 < p 5 p_1<p_2<p_3<p_4<p_5 p1<p2<p3<p4<p5,满足 a p 1 ≤ a p 2 = a p 3 = a p 4 ≥ a p 5 a_{p_1} \le a_{p_2} =a_{p_3}=a_{p_4} \ge a_{p_5} ap1ap2=ap3=ap4ap5 b p 2 = b p 3 = b p 4 = 1 b_{p_2}=b_{p_3}=b_{p_4}=1 bp2=bp3=bp4=1 的个数.
1 0 9 + 7 10^9+7 109+7 取模的值.
(保证每次修改后的 b i b_i bi 都与原来不同)

Solution \text{Solution} Solution

很适合练手的数据结构题.
一开始只想到树套树死卡空间然后被 @24KH 一语点破根本不用套.%%%
本题的关键就是动态统计加入一个点的贡献.
l i l_i li 表示满足 j < i , a j ≤ a i j<i,a_j\le a_i j<i,ajai j j j 的个数.
r i r_i ri 表示满足 j > i , a j ≤ a i j>i,a_j\le a_i j>i,ajai j j j 的个数.
那么我们考虑加入一个点 p p p 时的贡献:

p 作为中间元素

增加的方案数为:

∑ i < p < j ∧ a i = a p = a j l i × r j \large \sum_{i<p<j \land a_i=a_p=a_j}l_i\times r_j i<p<jai=ap=ajli×rj
也就是:
∑ i < p ∧ a i = a p l i × ∑ j > p ∧ a j = a p r j \large \sum_{i<p \land a_i=a_p}l_i\times \sum_{j>p \land a_j=a_p}r_j i<pai=apli×j>paj=aprj

p 作为两端元素

由于对称,单举 p p p 在最左侧为例.
增加的方案数为:
∑ p < i ∧ a i = a p l p × r i × ∑ p < j < i [ a j = a p ] \large \sum_{p<i\land a_i=a_p}l_p\times r_i\times\sum_{p<j<i}[a_j=a_p] p<iai=aplp×ri×p<j<i[aj=ap]
换句话说就是 ( p , i ) (p,i) (p,i) 之间每有一个权值相等的点, ( p , i ) (p,i) (p,i) 作为相等的两端就能产生一次贡献.

统计

离散化后对每个权值建一棵线段树.
∑ l i / r i \sum l_i/r_i li/ri 统计较为简单.
比较困难的就是统计:
∑ p < i ∧ a i = a p r i × ∑ p < j < i [ a j = a p ] \large \sum_{p<i\land a_i=a_p}r_i\times\sum_{p<j<i}[a_j=a_p] p<iai=apri×p<j<i[aj=ap]
这一项.
r a n s rans rans 为这一项的答案, l a n s lans lans 为这一项对称的答案,同时记录数的个数 s i z siz siz ∑ l i , ∑ r i \sum l_i,\sum r_i li,ri
合并左右儿子时:
s i z l s + s i z r s → s i z f a siz_{ls}+siz_{rs}\to siz_{fa} sizls+sizrssizfa
l s u m l s + l s u m r s → l s u m f a lsum_{ls}+lsum_{rs}\to lsum_{fa} lsumls+lsumrslsumfa
r s u m l s + r s u m r s → r s u m f a rsum_{ls}+rsum_{rs}\to rsum_{fa} rsumls+rsumrsrsumfa
l a n s l s + l a n s r s + l s u m l s × s i z r s → l a n s f a lans_{ls}+lans_{rs}+lsum_{ls}\times siz_{rs}\to lans_{fa} lansls+lansrs+lsumls×sizrslansfa
r a n s l s + r a n s r s + r s u m r s × s i z l s → r a n s f a rans_{ls}+rans_{rs}+rsum_{rs}\times siz_{ls}\to rans_{fa} ransls+ransrs+rsumrs×sizlsransfa
即可.

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double 
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e5+100;
const int mod=1e9+7;
inline ll read(){
  ll x(0),f(1);char c=getchar();
  while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
  while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  return x*f;
}

int n,m;
ll le[N],ri[N];
int id[N],bac[N];

#define mid ((l+r)>>1)
struct node{
  ll siz;
  ll lsum,rsum;
  ll lans,rans;
};
node merge(node a,node b){
  return (node){a.siz+b.siz,(a.lsum+b.lsum)%mod,(a.rsum+b.rsum)%mod,
      (a.lans+b.lans+a.lsum*b.siz)%mod,(a.rans+b.rans+a.siz*b.rsum)%mod};
}
struct tree{
  node o;
  int ls,rs;
}tr[N<<5];
int rt[N],tot;
inline int copy(int x){
  ++tot;tr[tot]=tr[x];
  return tot;
}
void add(int &k,int l,int r,int p,int w){
  if(!k) k=copy(k);
  if(l==r){
    tr[k].o.siz+=w;
    tr[k].o.lsum+=w*le[l];
    tr[k].o.rsum+=w*ri[l];
    return;
  }
  if(p<=mid) add(tr[k].ls,l,mid,p,w);
  else add(tr[k].rs,mid+1,r,p,w);
  tr[k].o=merge(tr[tr[k].ls].o,tr[tr[k].rs].o);
  //printf("  k=%d (%d %d) l")
}
//op=1:lsum
//op=2:lans
//op=3:rsum
//op=4:rans
node ask(int k,int l,int r,int x,int y){
  if(!k||x>y) return (node){0,0,0,0,0};
  if(x<=l&&r<=y) return tr[k].o;
  if(y<=mid) return ask(tr[k].ls,l,mid,x,y);
  else if(x>mid) return ask(tr[k].rs,mid+1,r,x,y);
  else return merge(ask(tr[k].ls,l,mid,x,y),ask(tr[k].rs,mid+1,r,x,y));
}

int q[N],cnt,a[N];
int f[N];
inline void Add(int p){
  for(;p<=cnt;p+=p&-p) ++f[p];
  return;
}
inline int Ask(int p){
  int res(0);
  for(;p;p-=p&-p) res+=f[p];
  return res;
}

inline ll calc(int pl){
  int o=rt[a[pl]];
  node L=ask(o,1,n,1,pl-1),R=ask(o,1,n,pl+1,n);
  return (L.lsum*R.rsum%mod+L.lans*ri[pl]%mod+R.rans*le[pl]%mod)%mod;
}
ll tt;
signed main(){
#ifndef ONLINE_JUDGE
  freopen("a.in","r",stdin);
  freopen("a.out","w",stdout);
#endif
  n=read();
  for(int i=1;i<=n;i++) q[i]=a[i]=read();
  sort(q+1,q+1+n);
  cnt=unique(q+1,q+1+n)-q-1;
  for(int i=1;i<=n;i++) a[i]=lower_bound(q+1,q+1+cnt,a[i])-q;
  for(int i=1;i<=n;i++){
    le[i]=Ask(a[i]);Add(a[i]);
  }
  memset(f,0,sizeof(f));
  for(int i=n;i>=1;i--){
    ri[i]=Ask(a[i]);Add(a[i]);
  }
  for(int i=1;i<=n;i++) id[i]=++bac[a[i]];
  //for(int i=1;i<=n;i++) printf("i=%d a=%d le=%lld ri=%lld id=%d\n",i,a[i],le[i],ri[i],id[i]);
  for(int i=1;i<=n;i++){
    tt+=calc(i);tt%=mod;
    add(rt[a[i]],1,n,i,1);
  }
  m=read();
  for(int i=1;i<=m;i++){
    int op=read(),x=read();
    if(op==1){
      add(rt[a[x]],1,n,x,-1);tt-=calc(x);
    }
    else{
      tt+=calc(x);add(rt[a[x]],1,n,x,1);
    }
    tt+=mod;tt%=mod;
    printf("%lld\n",tt);
  }
  return 0;
}
/*


*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值