SDKD 2017 Summer Team Training #12, tm--A(Queries )
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDKD 2017 Summer Team Training #12, tm--A(Queries )相关的知识,希望对你有一定的参考价值。
题目大意:
给你一个数组,给你如下几种操作:
s l r mod 查询区间【l,r】中模m等于mod的数字之和;
+ p r 将p位置的数加上r后模m;
- p r 将p位置的数减去r后模m;
解题思路:
一般进行区间查询,位置操作可以使用线段树或者树状数组解决(暂时只会树状数组);这题的特殊之处就在于要求模m等值;
由于m的值较小(m<10) 因此我们可以开一个二重的树状数组,第二重保存模m后的值;其余操作就是基本的树状~
#include <iostream> #include <string> #include <cstring> #include <vector> #include <set> #include <stack> #include <algorithm> #include <iterator> #include <queue> #include <cmath> #include <map> #include <cstdio> using namespace std; typedef long long ll; #define maxn 100007 #define INF 0x3f3f3f3f ll n,m,mod; ll a[maxn]; ll c[maxn][20]; int lowbit(int x) { return x&(-x); } void add(int pos,ll v,int mod) { // cout<<v<<" "<<mod<<"+++++++"<<endl; while(pos<=n) { c[pos][mod]+=v; pos+=lowbit(pos); } } ll ac_sum(int pos,int mod) { ll sum=0; while(pos>0) { //cout<<"++++"<<endl; sum+=c[pos][mod]; pos-=lowbit(pos); } return sum; } int main() { ios::sync_with_stdio(false); cin>>n>>m; for (int i=1;i<=n;i++) { //int a; cin>>a[i]; add(i,a[i],(a[i]%m)); } int k; cin>>k; while (k--) { string s; cin>>s; if (s[0]==‘s‘) { ll i,j,l; cin>>i>>j>>l; cout<<ac_sum(j,l)-ac_sum(i-1,l)<<endl; } else if (s[0]==‘+‘) { ll i,j; cin>>i>>j; add(i,-a[i],a[i]%m); a[i]+=j; add(i,a[i],a[i]%m); cout<<a[i]<<endl; } else if (s[0]==‘-‘) { ll i,j; cin>>i>>j; add(i,-a[i],a[i]%m); if (a[i]>=j) { a[i]-=j; } add(i,a[i],a[i]%m); cout<<a[i]<<endl; } } }
以上是关于SDKD 2017 Summer Team Training #12, tm--A(Queries )的主要内容,如果未能解决你的问题,请参考以下文章
SDKD 2017 Summer Single Training #03
SDUT 2021 summer team contest 1st(for 20)(补题)
Adding Reversed Numbers(summer2017)