• CSP模拟11



    (抖)

    A: One

    约瑟夫问题
    考试的时候没想出来 (wtcl)
    30pts: 直接大力模拟 用vis标记人是否死过 如果死过就不报数了

    60pts: STL vector可以直接碾过去
    考虑为什么30pts会慢 因为vis跳的时候很多没用的操作
    可以用pos链表记录一下该跳到哪个人 可以省去遍历死去人的时间

    正解是推柿子 其实之前讲过了类似解法但是并没有想出来
    大概是每次从0开始编号 然后柿子推一推就好了 主要思想是求出当前活着的人在上一轮的编号 然后递推就完了

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        freopen("one.in","r",stdin);
        freopen("one.out","w",stdout);
        int T;scanf("%d",&T);
        while(T--) {
            int n;scanf("%d",&n);
            int nw = 0;
            for(int i = 2;i <= n;++i) nw = (nw - i + 1 + n) % i;
            cout << nw + 1 << endl;
        }
        return 0;
    }
    
    

    B:哪一天她能重回我身边

    纯模拟
    记录几种情况随便打打

    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1000;
    const int now = maxn;
    char s[maxn];
    int cnt[maxn << 1][maxn << 1];
    int k;
    
    int main(){
        freopen("block.in","r",stdin);
        freopen("block.out","w",stdout);
        int T;scanf("%d",&T);
        while(T--) {
            memset(cnt,0,sizeof(cnt));
            scanf("%d",&k); scanf("%s",s + 1);
            int len = strlen(s + 1);
            if(k == 1) {
                int x = 0,y = 0;
                cnt[x + now][y + now]++;
                int Max = 1;
                for(int i = 1;i <= len;++i) {
                    if(s[i] == 'N') y++;
                    if(s[i] == 'S') y--;
                    if(s[i] == 'E') x++;
                    if(s[i] == 'W') x--;
                    ++cnt[x + now][y + now];
                    if(cnt[x + now][y + now] > Max) Max = cnt[x + now][y + now];
                }
                printf("%d
    %d
    %d
    ",x,y,Max);
            }
            else {
                int cur = 1;
                int x = 0,y = 0;
                cnt[x + now][y + now]++;
                int Max = 1;
                for(int i = 1;i <= len;++i) {
                    if(cur == 1) {
                        if(s[i] == 'N') {
                            y++;
                            for(int j = y;j <= y + k - 1;++j) {
                                cnt[x + now][j + now]++;
                                if(cnt[x + now][j + now] > Max) Max = cnt[x + now][j + now];
                            }
                            cur = 2;
                        }
                        if(s[i] == 'S') {
                            y -= k;
                            for(int j = y;j <= y + k - 1;++j) {
                                cnt[x + now][j + now]++;
                                if(cnt[x + now][j + now] > Max) Max = cnt[x + now][j + now];
                            }
                            cur = 2;
                        }
                        if(s[i] == 'E') {
                            x++;
                            for(int j = x;j <= x + k - 1;++j) {
                                cnt[j + now][y + now]++;
                                if(cnt[j + now][y + now] > Max) Max = cnt[j + now][y + now];
                            }
                            cur = 3;
                        }
                        if(s[i] == 'W') {
                            x -= k;
                            for(int j = x;j <= x + k - 1;++j) {
                                cnt[j + now][y + now]++;
                                if(cnt[j + now][y + now] > Max) Max = cnt[j + now][y + now];
                            }
                            cur = 3;
                        }
                        //cout << cur << endl;
                        continue;
                    }
                    if(cur == 2) {
                        if(s[i] == 'N') {
                            y += k;
                            cnt[x + now][y + now]++;
                            if(cnt[x + now][y + now] > Max) Max = cnt[x + now][y + now];
                            cur = 1;
                        }
                        if(s[i] == 'S') {
                            y--;
                            cnt[x + now][y + now]++;
                            if(cnt[x + now][y + now] > Max) Max = cnt[x + now][y + now];
                            cur = 1;
                        }
                        if(s[i] == 'E') {
                            x++;
                            for(int j = y;j <= y + k - 1;++j) {
                                cnt[x + now][j + now]++;
                                if(cnt[x + now][j + now] > Max) Max = cnt[x + now][j + now];
                            }
                            cur = 2;
                        }
                        if(s[i] == 'W') {
                            x--;
                            for(int j = y;j <= y + k - 1;++j) {
                                cnt[x + now][j + now]++;
                                if(cnt[x + now][j + now] > Max) Max = cnt[x + now][j + now];
                            }
                            cur = 2;
                        }
                        //cout << cur << endl;
                        continue;
                    }
                    if(cur == 3) {
                        if(s[i] == 'N') {
                            y++;
                            for(int j = x;j <= x + k - 1;++j) {
                                cnt[j + now][y + now]++;
                                if(cnt[j + now][y + now] > Max) Max = cnt[j + now][y + now];
                            }
                            cur = 3;
                        }
                        if(s[i] == 'S') {
                            y--;
                            for(int j = x;j <= x + k - 1;++j) {
                                cnt[j + now][y + now]++;
                                if(cnt[j + now][y + now] > Max) Max = cnt[j + now][y + now];
                            }
                            cur = 3;
                        }
                        if(s[i] == 'E') {
                            x += k;
                            cnt[x + now][y + now]++;
                            if(cnt[x + now][y + now] > Max) Max = cnt[x + now][y + now];
                            cur = 1;
                        }
                        if(s[i] == 'W') {
                            x--;
                            cnt[x + now][y + now]++;
                            if(cnt[x + now][y + now] > Max) Max = cnt[x + now][y + now];
                            cur = 1;
                        }
                        //cout << cur << endl;
                        continue;
                    }
                }
                if(cur == 1) {
                    printf("%d
    %d
    %d
    ",x,y,Max);
                }
                if(cur == 2) {
                    for(int i = 1;i <= k;++i) printf("%d ",x);
                    printf("
    ");
                    for(int i = y;i <= y + k - 1;++i) printf("%d ",i);
                    printf("
    %d
    ",Max);
                }
                if(cur == 3) {
                    for(int i = x;i <= x + k - 1;++i) printf("%d ",i);
                    printf("
    ");
                    for(int i = 1;i <= k;++i) printf("%d ",y);
                    printf("
    %d
    ",Max);
                }
            }
        }
        return 0;
    }
    

    C: 数字

    然而似乎并不会
    害怕.jpg

    D: 甜圈

    两种解题方法
    正解 : 对操作哈希 然后求有多少个叶子节点的值等于我们要求的值就好了 对于每次区间一次操作 就是一次区间乘带一次区间加 最后把所有lazy 都pushdown下去统计答案
    另一种思路: 可以保存当前区间进行过哪些次操作 l 和 r表示时间最早和最晚的操作是什么 对于一个区间 如果不合法就让l 和 r都等于-1 如果并没有进行过任何操作就是0
    对于0的状态显然一定合法 然后如果对于区间进行了一次修改 那就保留一个lazy 标记 然后如果可以和子区间中的r进行合并就让它合并 最后大力pushdown 然后统计答案

    
    
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef unsigned long long ull;
    
    const int maxn = 2e5 + 10;
    const ull base = 233;
    int ans = 0;
    
    ull t[maxn << 2];
    ull add[maxn << 2]; //加法标记
    ull mul[maxn << 2];
    
    void pushdown(int rt,int l,int r){
    	int mid = l + r >> 1;
    	t[rt << 1] = t[rt << 1] * mul[rt] + add[rt] * (mid - l + 1);
    	t[rt << 1 | 1] = t[rt << 1 | 1] * mul[rt] + add[rt] * (r - mid);
    	add[rt << 1] = add[rt << 1] * mul[rt] + add[rt];
    	add[rt << 1 | 1] = add[rt << 1 | 1] * mul[rt] + add[rt];
    	mul[rt << 1] *= mul[rt];
    	mul[rt << 1 | 1] *= mul[rt];
    	mul[rt] = 1; add[rt] = 0;
    }
    
    void modify(int rt,int l,int r,int L,int R,int k){
    	if(L <= l && R >= r) return t[rt] += k * (r - l + 1),add[rt] += k,void();
    	int mid = l + r >> 1;
    	pushdown(rt,l,r);
    	if(L <= mid) modify(rt << 1,l,mid,L,R,k);
    	if(R > mid) modify(rt << 1 | 1,mid + 1,r,L,R,k);
    	t[rt] = t[rt << 1] + t[rt << 1 | 1];
    }
    
    void mult(int rt,int l,int r,int L,int R,int k){
    	if(L <= l && R >= r) return add[rt] *= k,mul[rt] *= k,t[rt] *= k,void();
    	int mid = l + r >> 1;
    	pushdown(rt,l,r);
    	if(L <= mid) mult(rt << 1,l,mid,L,R,k);
    	if(R > mid) mult(rt << 1 | 1,mid + 1,r,L,R,k);
    	t[rt] = t[rt << 1] + t[rt << 1 | 1];
    }
    
    int ask(int rt,int l,int r,int L,int R){
    	if(L <= l && R >= r) return t[rt];
    	int mid = l + r >> 1;
    	pushdown(rt,l,r);
    	if(R <= mid) return ask(rt << 1,l,mid,L,R);
    	if(L > mid) return ask(rt << 1 | 1,mid + 1,r,L,R);
    	return ask(rt << 1,l,mid,L,R) + ask(rt << 1 | 1,mid + 1,r,L,R);
    }
    
    int main(){
    	freopen("deco.in","r",stdin);
    	freopen("deco.out","w",stdout);
    	int n,K,T;scanf("%d%d%d",&n,&K,&T);
    	memset(mul,1,sizeof(mul));
    	for(int i = 1;i <= T;++i) {
    		int l,r,x;scanf("%d%d%d",&l,&r,&x);
    		mult(1,1,n,l,r,base);
    		modify(1,1,n,l,r,x);
    	}
    	int T_T = 0;
    	for(int i = 1;i <= K;++i) T_T = T_T * base + i;
    	for(int i = 1;i <= n;++i) if(ask(1,1,n,i,i) == T_T) ans++;
    	cout << ans << endl;
    	return 0;
    }
    
    
    如初见 与初见
  • 相关阅读:
    静态代理和动态代理
    Tomcat的作用思考及NIO的应用(要区分Java NIO和操作系统的NIO模型)
    破坏双亲委托机制的一些情况---Tomcat和JDBC,破坏后的安全问题
    springboot cache---本地缓存的使用
    springboot--异步执行的方法及定时执行的方法
    springboot--事务的使用
    数据结构--堆排序
    数据结构--树的非递归遍历
    最长公共子串的长度和构造
    2015 小结及其2016计划
  • 原文地址:https://www.cnblogs.com/HISKrrr/p/13782858.html
Copyright © 2020-2023  润新知