zoukankan      html  css  js  c++  java
  • 6.26——集训模拟赛1【考炸的一天】

    前言

    (Day5)了,复习正式结束,结果第一天就水到爆,下午调代码还调半天,吐了吐了。

    NO.1 信息传递

    题目

    (n) 个同学(编号为 (1)(n) )正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为 (i)的同学的信息传递对象是编号为 (T_i) 的同学。

    游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息, 但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自 己的生日时,游戏结束。请问该游戏一共可以进行几轮?

    输入格式

    输入共(2)行。 第(1)行包含(1)个正整数 (n) ,表示 (n) 个人。

    (2)行包含 (n) 个用空格隔开的正整数 (T_1,T_2,⋯⋯,T_n)其中第 (i) 个整数 (T_i) 表示编号为 (i) 的同学的信息传递对象是编号为 (T_i) 的同学, (T_i≤n)(T_i≠i)

    数据保证游戏一定会结束。

    输出格式

    输出共(1)行,包含(1)个整数,表示游戏一共可以进行多少轮。

    input

    5
    2 4 2 3 1

    output

    3

    分析

    根据题目很容易就能知道,这些数据一定是一个环状,因为问可以进行多少轮,所以肯定有一个人听到自己的信息就结束了,所以就是(tarjan)求最小环,当然,并查集,暴搜也是可行的,不过我还是觉得(tarjan)是最容易的。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+5;
    struct Node{
        int v,next;
    }e[maxn<<2];
    int n,dfn[maxn],low[maxn],vis[maxn],tot,ans=maxn;
    stack<int>st;
    int head[maxn];
    void add(int x,int y){
        e[++tot].v = y;
        e[tot].next = head[x];
        head[x] = tot;
    }
    void tarjan(int x){//tarjan板子,求最小环
        low[x]=dfn[x]=++tot;
        st.push(x);
        vis[x]=1;
        for(int i=head[x];i;i = e[i].next){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(vis[v]){
                low[x]=min(low[x],dfn[v]);
            }
        }
        if(low[x]==dfn[x]){
            int cnt=0;
            while(1){
                int now=st.top();
                st.pop();
                vis[x]=0;
                cnt++;
                if(now==x) break;
            }
            if(cnt>1) ans=min(ans,cnt);
        }
    }
    
    
    int main(){
        scanf("%d",&n);
        int x;
        for(int i=1;i<=n;i++){//建边
            scanf("%d",&x);
            add(i,x);           
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]){
                tarjan(i);
            }
        }
        printf("%d
    ",ans);
    }
    

    NO.2 传染病控制

    题目描述

    近来,一种新的传染病肆虐全球。蓬莱国也发现  了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延。不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒  携带者,更没有研制出疫苗以保护易感人群。于是,蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播。经过  (WHO)(世界卫生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究消楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有  效的控制办法。

    问题描述

    研究表明,这种传染病的传播具有两种很特殊的性质; 
    第一是它的传播途径是树型的,一个人(X)只可能被某个特定的人(Y)感染,只要(Y)不得病,或者是(XY)之间的传播途径被切断,则X就不会得病。 
    第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一代患者,而不会再传播给下一代。 
    这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中  心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也  就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个  切断传播途径的顺序,以使尽量少的人被感染。你的程序要针对给定的树,找出合适的切断顺序。

    输入

    输入格式的第一行是两个整数(n(1≤n≤300))(p)。接下来(p)行,每一行有两个整数(i)(j),表示节点(i)(j)间有边相连(意即,第i人和第j人之间有传播途径相连,注意:可能是(i)(j)也可能是(j)(i))。其中节点(1)是已经被感染的患者。 
    对于给定的输入数据,如果不切断任何传播途径,则所有人都会感染。

    输出

    只有一行,输出总共被感染的人数。

    样例输入

    7 6
    1 2
    1 3
    2 4
    2 5
    3 6
    7 3

    样例输出

    3

    分析

    由于树形传播,所以肯定是每一部分节点都是有深度的,所以就考虑按照深度来枚举。首先建树毫无疑问。然后进行第一次的深搜,目的是把所有的点的深度都查找出来。并且记录每一个节点的子节点个数,用(siz)数组记录。深搜结束后,把每一个深度的点都用(vector)数组存下来,然后就是第二遍深搜,在每一个深度下,枚举每个点是否被切断,枚举完毕后要更改成未切断的状态。其中(vis)数组代表的是当前点是否断开,当然,如果父节点断开,那么子节点也就全部都需要标记。如果搜到了最底层或者节点全部被标记了,那么肯定就是要记录答案(也就是最大的节点数减去被标记节点数)然后就输出就好了,具体看代码。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 305;
    struct Node{//边表建树
        int to,next;
    }e[maxn<<2];
    int ans;
    int n,m;
    int head[maxn],cnt;
    int fa[maxn],siz[maxn],deep[maxn],madep,vis[maxn];
    vector<int>k[maxn];//记录每一个深度下的所有节点
    void add(int x,int y){//建树
        e[++cnt].to = y;
        e[cnt].next = head[x];
        head[x] = cnt;
    }
    void dfs(int x,int f,int dep){//第一遍深搜,找出每个节点的子树个数和深度
        fa[x] = f;
        siz[x] = 1;
        deep[x] = dep;
        madep = max(madep,dep);
        for(int i=head[x];i;i = e[i].next){
            if(e[i].to != f){
                dfs(e[i].to,x,dep+1);
                siz[x] += siz[e[i].to];
            }
        }
    }
    void Dfs(int dep,int now){//第二遍深搜,每个深度(每层)一次枚举需要断开的点,并标记求答案
        if(dep == madep+1){
            ans = min(now,ans);
            return;
        }
        for(int i=0;i<k[dep].size();++i){
            if(vis[fa[k[dep][i]]]){//如果父亲被标记,儿子也一定被标记
                vis[k[dep][i]] = 1;
            }
            else vis[k[dep][i]] = 0;//未被标记
        }
        bool f = 1;//是否全部被标记
        for(int i=0;i<k[dep].size();i++){
            if(!vis[k[dep][i]])f = 0;
        }
        if(f){//全部被标记就记录答案跳出
            ans = min(now,ans);
            return;
        }
        for(int i=0;i<k[dep].size();++i){//枚举每一层的每个点
    		if(vis[k[dep][i]])continue;
    		vis[k[dep][i]]=1;//断开标记
    		Dfs(dep+1,now-siz[k[dep][i]]);//深度加一,结果减去节点子树大小
    		vis[k[dep][i]]=0;//重新归零,进行下一次标记其他点
    	}
    }
    
    int main(){
        cin>>n>>m;
        for(int i=1,x,y;i<=m;++i){
            cin>>x>>y;
            add(x,y);
            add(y,x);
        }
        dfs(1,0,1);
        for(int i=1;i<=n;++i){
            k[deep[i]].push_back(i);
        }
        ans = n;
        Dfs(2,n);
        cout<<ans;
        return 0;
    }
    

    NO.3 排列perm

    Description

    给一个数字串(s)和正整数(d), 统计(s)有多少种不同的排列能被(d)整除(可以有前导(0))。例如(123434)(90)种排列能被(2)整除,其中末位为(2)的有(30)种,末位为(4)的有(60)种。

    Input

    输入第一行是一个整数(T),表示测试数据的个数,以下每行一组(s)(d),中间用空格隔开。(s)保证只包含数字(0, 1, 2, 3, 4, 5, 6, 7, 8, 9.)

    Output

    每个数据仅一行,表示能被d整除的排列的个数。

    Sample Input

    7
    000 1
    001 1
    1234567890 1
    123434 2
    1234 7
    12345 17
    12345678 29

    Sample Output

    1
    3
    3628800
    90
    3
    6
    1398

    HINT

    在前三个例子中,排列分别有(1), (3), (3628800)种,它们都是(1)的倍数。

    (100\%)的数据满足:s的长度不超过(10, 1<=d<=1000, 1<=T<=15)

    分析

    看到这种和谐又弱的数据范围,状压(dp)显然实锤了。然后当时我就无了思路,主要是不知道到底如何转移,考完以后听别人讲的才知道。首先(dp)当然是要有方程和(dp)数组的,我们定义一个(dp[i][j]),代表状态为(i)时,余数为(j)的方案数。我们从第一位逐一向后枚举,让每一位都填入一个数,并且让当前的余数(j)进一位也就是乘上(10)再加上我们在后边填入的那个数,最后在模上(mod),这就是一个状态转移。最后的答案就是状态为全部填入(如果数列长度为(len)的话,那么全部填入的状态则是((1<<len)-1))且余数为(0),值得注意的一个地方就是开始读入数列中数字的时候,把每个数的数量都用(cnt)数组记录一下,最终的答案需要除以数字数量的全排列(全排列直接初始化,因为最大才是(10)),最终状态转移方程就是:

    [f[i|(1<<j)][(k imes 10+a[j+1])\%d]+=f[i][k] ]

    其中(i)为枚举的状态,(j)为放入第几位,(k)为余数。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 15;
    int f[1<<maxn][1100];
    int a[maxn];
    char s[maxn];
    int cnt[maxn];
    int T,d;
    int J[]={0,1,2,6,24,120,720,5040,40320,362880,3628800};//初始化1到10的全排列
    int main(){
        cin>>T;
        while(T--){
            memset(cnt,0,sizeof(cnt));
            memset(f,0,sizeof(f));
            cin>>s>>d;
            int len = strlen(s);
            for(int i=0;i<len;++i){
                a[i+1] = s[i] - '0';
                cnt[a[i+1]]++;//预处理数字为a[i+1]的个数
            }
            f[0][0] = 1;
            int lim = (1<<len);
            for(int i=0;i<lim;++i){//枚举状态
                for(int k=0;k<d;++k){//枚举余数
                    if(f[i][k])//优化效率,0的时候就不用加了
                    for(int j=0;j<len;++j){//枚举放第几位
                        if((i & (1<<j)) == 0){
                            f[i|(1<<j)][(k*10+a[j+1])%d] += f[i][k];//状态转移
                        }
                    }
                }
            }
            int ans = f[lim-1][0];//答案就是状态为全部填入,余数为0的情况数
            for(int i=0;i<=9;++i){
                if(cnt[i]){
                    ans /= J[cnt[i]];//答案除以有几个同样数字的全排列,因为数字一样的话不管哪个放在一个位置都是一种
                }
            }
            cout<<ans<<endl;
        }
    
    }
    

    顺便膜拜一下机房大佬lc,下边是他的打表代码(虽然t了,但是正确率是真的优秀)这耐心和思维的缜密真是没谁了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=4e6+5;
    ll ans;
    map<ll,ll> mp;
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            mp.clear();
            ans=0;
            char s[50];
            ll xx;
            scanf("%s",s);
            scanf("%lld",&xx);
            int len=strlen(s);
            if(len==1){
                ll now=s[0]-'0';
                if(now%xx==0) printf("1
    ");
                else printf("0
    ");
            } else if(len==2){
                for(int i=0;i<=1;i++){
                    for(int j=0;j<=1;j++){
                        if(j==i) continue;
                        ll now=(s[i]-'0')*10ll+(s[j]-'0');
                        if(mp[now]==1) continue;
                        mp[now]=1;
                        if(now%xx==0) ans++;
                    }
                }
                printf("%lld
    ",ans);
            } else if(len==3){
                for(int i=0;i<len;i++){
                    for(int j=0;j<len;j++){
                        if(j==i) continue;
                        for(int k=0;k<len;k++){
                            if(k==j || k==i) continue;
                            ll now=(s[i]-'0')*100ll+(s[j]-'0')*10ll+(s[k]-'0');
                            if(mp[now]==1) continue;
                            mp[now]=1;
                            if(now%xx==0) {
                                ans++;
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            } else if(len==4){
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                ll now=(s[i1]-'0')*1000ll+(s[i2]-'0')*100ll+(s[i3]-'0')*10ll+(s[i4]-'0');
                                if(mp[now]==1) continue;
                                mp[now]=1;
                                if(now%xx==0){
                                    ans++;
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            } else if(len==5){
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                for(int i5=0;i5<len;i5++){
                                    if(i5==i1 || i5==i2 || i5==i3 || i5==i4) continue;
                                    ll now=(s[i1]-'0')*10000ll+(s[i2]-'0')*1000ll+(s[i3]-'0')*100ll+(s[i4]-'0')*10ll+(s[i5]-'0');
                                    if(mp[now]==1) continue;
                                    mp[now]=1;
                                    if(now%xx==0){
                                        ans++;
                                    }
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            } else if(len==6){
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                for(int i5=0;i5<len;i5++){
                                    if(i5==i1 || i5==i2 || i5==i3 || i5==i4) continue;
                                    for(int i6=0;i6<len;i6++){
                                        if(i6==i1 || i6==i2 || i6==i3 || i6==i4 || i6==i5) continue;
                                        ll now=(s[i1]-'0')*100000ll+(s[i2]-'0')*10000ll+(s[i3]-'0')*1000ll+(s[i4]-'0')*100ll;
                                        now+=(s[i5]-'0')*10ll+(s[i6]-'0');
                                        if(mp[now]==1) continue;
                                        mp[now]=1;
                                        if(now%xx==0){
                                            ans++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            } else if(len==7){
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                for(int i5=0;i5<len;i5++){
                                    if(i5==i1 || i5==i2 || i5==i3 || i5==i4) continue;
                                    for(int i6=0;i6<len;i6++){
                                        if(i6==i1 || i6==i2 || i6==i3 || i6==i4 || i6==i5) continue;
                                        for(int i7=0;i7<len;i7++){
                                            if(i7==i1 || i7==i2 || i7==i3 || i7==i4 || i7==i5 || i7==i6) continue;
                                            ll now=(s[i1]-'0')*1000000ll+(s[i2]-'0')*100000ll+(s[i3]-'0')*10000ll+(s[i4]-'0')*1000ll;
                                            now+=(s[i5]-'0')*100ll+(s[i6]-'0')*10ll+(s[i7]-'0');
                                            if(mp[now]==1) continue;
                                            mp[now]=1;
                                            if(now%xx==0){
                                                ans++;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            } else if(len==8){
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                for(int i5=0;i5<len;i5++){
                                    if(i5==i1 || i5==i2 || i5==i3 || i5==i4) continue;
                                    for(int i6=0;i6<len;i6++){
                                        if(i6==i1 || i6==i2 || i6==i3 || i6==i4 || i6==i5) continue;
                                        for(int i7=0;i7<len;i7++){
                                            if(i7==i1 || i7==i2 || i7==i3 || i7==i4 || i7==i5 || i7==i6) continue;
                                            for(int i8=0;i8<len;i8++){
                                            if(i8==i1 || i8==i2 || i8==i3 || i8==i4 || i8==i5 || i8==i6 || i8==i7) continue;
                                                ll now=(s[i1]-'0')*10000000ll+(s[i2]-'0')*1000000ll+(s[i3]-'0')*100000ll+(s[i4]-'0')*10000ll;
                                            now+=(s[i5]-'0')*1000ll+(s[i6]-'0')*100ll+(s[i7]-'0')*10ll+(s[i8]-'0');
                                            if(mp[now]==1) continue;
                                            mp[now]=1;
                                            if(now%xx==0){
                                                ans++;
                                            }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            }  else if(len==9){
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                for(int i5=0;i5<len;i5++){
                                    if(i5==i1 || i5==i2 || i5==i3 || i5==i4) continue;
                                    for(int i6=0;i6<len;i6++){
                                        if(i6==i1 || i6==i2 || i6==i3 || i6==i4 || i6==i5) continue;
                                        for(int i7=0;i7<len;i7++){
                                            if(i7==i1 || i7==i2 || i7==i3 || i7==i4 || i7==i5 || i7==i6) continue;
                                            for(int i8=0;i8<len;i8++){
                                            if(i8==i1 || i8==i2 || i8==i3 || i8==i4 || i8==i5 || i8==i6 || i8==i7) continue;
                                                for(int i9=0;i9<len;i9++){
                                                if(i9==i1 || i9==i2 || i9==i3 || i9==i4 || i9==i5 || i9==i6 || i9==i7 || i9==i8) continue;
                                                    ll now=(s[i1]-'0')*100000000ll+(s[i2]-'0')*10000000ll+(s[i3]-'0')*1000000ll+(s[i4]-'0')*100000ll;
                                            now+=(s[i5]-'0')*10000ll+(s[i6]-'0')*1000ll+(s[i7]-'0')*100ll+(s[i8]-'0')*10ll+(s[i9]-'0');
                                            if(mp[now]==1) continue;
                                            mp[now]=1;
                                            if(now%xx==0){
                                                ans++;
                                            }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            } else {
                for(int i1=0;i1<len;i1++){
                    for(int i2=0;i2<len;i2++){
                        if(i1==i2) continue;
                        for(int i3=0;i3<len;i3++){
                            if(i3==i1 || i3==i2) continue;
                            for(int i4=0;i4<len;i4++){
                                if(i4==i1 || i4==i2 || i4==i3) continue;
                                for(int i5=0;i5<len;i5++){
                                    if(i5==i1 || i5==i2 || i5==i3 || i5==i4) continue;
                                    for(int i6=0;i6<len;i6++){
                                        if(i6==i1 || i6==i2 || i6==i3 || i6==i4 || i6==i5) continue;
                                        for(int i7=0;i7<len;i7++){
                                            if(i7==i1 || i7==i2 || i7==i3 || i7==i4 || i7==i5 || i7==i6) continue;
                                            for(int i8=0;i8<len;i8++){
                                            if(i8==i1 || i8==i2 || i8==i3 || i8==i4 || i8==i5 || i8==i6 || i8==i7) continue;
                                                for(int i9=0;i9<len;i9++){
                                                if(i9==i1 || i9==i2 || i9==i3 || i9==i4 || i9==i5 || i9==i6 || i9==i7 || i9==i8) continue;
                                                    for(int i10=0;i10<len;i10++){
                                                    if(i10==i1 || i10==i2 || i10==i3 || i10==i4 || i10==i5 || i10==i6 || i10==i7) continue;
                                                     if( i10==i8 || i10==i9) continue;
                                                        ll now=(s[i1]-'0')*1000000000ll+(s[i2]-'0')*100000000ll+(s[i3]-'0')*10000000ll;
                                                        now+=(s[i4]-'0')*1000000ll;
                                                        now+=(s[i5]-'0')*100000ll+(s[i6]-'0')*10000ll+(s[i7]-'0')*1000ll+(s[i8]-'0')*100ll;
                                                        now+=(s[i9]-'0')*10ll+(s[i10]-'0');
                                                        if(mp[now]==1) continue;
                                                        mp[now]=1;
                                                        if(now%xx==0){
                                                        ans++;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    

    NO.4 最大数

    题目描述

    现在请求你维护一个数列,要求提供以下两种操作:

    1、 查询操作。

    语法:(Q L)

    功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。

    限制:(L)不超过当前数列的长度。((L>0))
    2、 插入操作。

    语法:(A n)

    功能:将(n)加上(t),其中(t)是最近一次查询操作的答案(如果还未执行过查询操作,则(t=0)),并将所得结果对一个固定的常数(D)取模,将所得答案插入到数列的末尾。

    限制:(n)是整数(可能为负数)并且在长整范围内。

    注意:初始时数列是空的,没有一个数。

    输入格式

    第一行两个整数,(M)(D),其中(M)表示操作的个数((M≤200,000))(D)如上文中所述,满足((0<D<2,000,000,000))

    接下来的(M)行,每行一个字符串,描述一个具体的操作。语法如上文所述。

    输出格式

    对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

    输入

    5 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2

    输出

    96
    93
    96

    分析

    看到这些加入,修改,自然而然就想到了线段树(可惜我写的暴力,线段树调不过,这次就炸了)其实就是单点修改,区间查询,只不过在修改的时候不是取区间和,而是区间最大值,然后就是线段树的板子了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll modd,m,tt,line;
    ll a[2000001];//记录区间最大值
    ll Find(ll p,ll l,ll r,ll nl,ll nr){//区间查询
    	if (nl<=l&&r<=nr)return a[p];
        ll mid=(l+r)/2;
        ll minn=-0x3ffffffff;
        if (nl<=mid)minn=Find(p*2,l,mid,nl,nr);
        if (nr>mid)minn=max(minn,Find(p*2+1,mid+1,r,nl,nr));
        return minn;
    }
    void Add(ll p,ll l,ll r,ll w,ll v){//单点修改
    	if(l==r){a[p]=v;return;}
    	ll mid=(l+r)/2;
    	if(w<=mid)Add(p*2,l,mid,w,v);
    	else Add(p*2+1,mid+1,r,w,v);
    	a[p]=max(a[p*2],a[p*2+1]);
    }
    int main(){
    	cin>>m>>modd;
    	for(int i=1;i<=m;i++){
    		char s;
    		cin>>s;
    		if(s=='A'){
    			ll ls;
                            cin>>ls;
    			line++;
    			Add(1,1,m,line,(tt+ls)%modd);
    		}
    		else {
    			ll ls;
                            cin>>ls;
    			if(!ls)tt=0;
    			else
    			tt=Find(1,1,m,line-ls+1,m);//记录上一次查询的答案
    			printf("%lld
    ",tt);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    HttpClient上传文件(转)
    数据库查询结果导出到excel
    docker报错“net/http: TLS handshake timeout”
    java线程的几个状态和锁的作用范围
    简单管理WPF及Winform所有弹出窗体
    FastJson学习
    基于消息中间件实现流量削峰
    pandas
    DBSCAN
    A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead
  • 原文地址:https://www.cnblogs.com/Vocanda/p/13195642.html
Copyright © 2011-2022 走看看