18.10.6 考试总结

这道题就是一道模拟题 也没有什么细节 反正蛮好写的

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1005;
int hx, hy, lx, ly, now, ma, h;
int vis[2 * N][2 * N], T;
char opt[105];

void deal(int sta, char opt, int del) {

    if(sta == 1) {
        if(opt == ‘E‘ || opt == ‘W‘) {
            if(opt == ‘E‘) hx = hx + h, lx = lx + 1;
            if(opt == ‘W‘) hx = hx - 1, lx = lx - h;
            for(int i = lx;i < hx;i ++) {
                vis[i][ly] += del;
                if(vis[i][ly] > ma) ma = vis[i][ly];
            }
            now = 3; return ;
        }
        if(opt == ‘N‘ || opt == ‘S‘) {
            if(opt == ‘N‘) hy = hy + h, ly = ly + 1;
            if(opt == ‘S‘) hy = hy - 1, ly = ly - h;
            for(int i = ly;i < hy;i ++) {
                vis[lx][i] += del;
                if(vis[lx][i] > ma) ma = vis[lx][i];
            }
            now = 2; return ;
        }
    }
    if(sta == 2) {
        if(opt == ‘E‘ || opt == ‘W‘) {
            if(opt == ‘E‘) hx = hx + 1, lx = lx + 1;
            if(opt == ‘W‘) hx = hx - 1, lx = lx - 1;
            for(int i = ly;i < hy;i ++) {
                vis[lx][i] += del;
                if(vis[lx][i] > ma) ma = vis[lx][i];
            }
            now = 2; return ;
        }
        if(opt == ‘N‘ || opt == ‘S‘) {
            if(opt == ‘N‘) hy = hy + 1, ly = ly + h;
            if(opt == ‘S‘) hy = hy - h, ly = ly - 1;
            for(int i = ly;i < hy;i ++) {
                vis[lx][i] += del;
                if(vis[lx][i] > ma) ma = vis[lx][i];
            }
            now = 1; return ;
        }
    }
    if(sta == 3) {
        if(opt == ‘E‘ || opt == ‘W‘) {
            if(opt == ‘E‘) hx = hx + 1, lx = lx + h;
            if(opt == ‘W‘) hx = hx - h, lx = lx - 1;
            for(int i = lx;i < hx;i ++) {
                vis[i][ly] += del;
                if(vis[i][ly] > ma) ma = vis[i][ly];
            }
            now = 1; return ;
        }
        if(opt == ‘N‘ || opt == ‘S‘) {
            if(opt == ‘N‘) hy = hy + 1, ly = ly + 1;
            if(opt == ‘S‘) hy = hy - 1, ly = ly - 1;
            for(int i = lx;i < hx;i ++) {
                vis[i][ly] += del;
                if(vis[i][ly] > ma) ma = vis[i][ly];
            }
            now = 3; return ;
        }
    }
}

void Solve( ) {

    while(T --) {
        scanf("%d",& h);
        scanf("%s",opt + 1); int len = strlen(opt + 1);
        lx = 1000, ly = 1000, hx = 1001, hy = 1001;
        ma = 1; now = 1; vis[1000][1000] = 1;
        for(int i = 1;i <= len;i ++) {
            deal(now, opt[i], 1);
        }
        if(now == 1) {
            printf("%d\n%d\n", lx - 1000, ly - 1000);
        }
        if(now == 2) {
            for(int i = ly;i < hy;i ++) {
                if(i != hy - 1) printf("%d ", lx - 1000);
                else printf("%d\n", lx - 1000);
            }
            for(int i = ly;i < hy;i ++) {
                if(i != hy - 1) printf("%d ", i - 1000);
                else printf("%d\n", i - 1000);
            }
        }
        if(now == 3) {
            for(int i = lx;i < hx;i ++) {
                if(i != hx - 1) printf("%d ", i - 1000);
                else printf("%d\n", i - 1000);
            }
            for(int i = lx;i < hx;i ++) {
                if(i != hx - 1) printf("%d ", ly - 1000);
                else printf("%d\n", ly - 1000);
            }
        }
        printf("%d\n",ma);
        lx = 1000, ly = 1000, hx = 1001, hy = 1001;
        ma = 0; now = 1; vis[1000][1000] = 0;
        for(int i = 1;i <= len;i ++) {
            deal(now, opt[i], -1);
        }
    }
}

int main( ) {

    freopen("block.in","r",stdin);
    freopen("block.out","w",stdout);
    scanf("%d",& T);
    Solve( );
}

第二题是一个数论题 然后我们都没有弄出来 就先不改了

这道题本来是哈希的 然后zjj同学写了可持久化线段树 我就学习了一波可持久化线段树

哈希的做法是 对于每一个节点 维护一个对他进行操作的哈希值

比如我对这个节点进行过$12345$操作 那么就将这个玩意儿变成一个哈希值 就是那个乘$base$ + ‘char‘的那个玩意儿  

最后查询每个节点和标准串的哈希值 如果一样答案就加一

那么现在是zjjdalao的做法 是对于每一个节点维护三个值 $max,min,tag$

分别表示在该区间内进行的操作的最大值 最小值 以及这个区间内是否还有合法的 如果有就是$1$ 否则为$0$

然后一些东西写在注释里面了

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 2 * 1e5 + 5;
int n,k,t,ans;
struct node {

    int ma, mi;
    bool tag;
    node(int mi = 0, int ma = 0, bool tag = 0) : mi(mi),ma(ma),tag(tag) { }
}f[4 * N];

void update(int o) {

    if(f[2 * o].tag && f[2 * o + 1].tag) {
        f[o] = node(min(f[2 * o].mi, f[2 * o + 1].mi), max(f[2 * o].ma, f[2 * o + 1].ma), 1);
    }
    else if(f[2 * o].tag) {
        f[o] = node(f[2 * o].mi, f[2 * o].ma, 1);
    }
    else if(f[2 * o + 1].tag) {
        f[o] = node(f[2 * o + 1].mi, f[2 * o + 1].ma, 1);
    }
    else f[o].tag = 0;
}

void build(int o, int l, int r) {

    if(l == r) {
        f[o] = node(0, 0, 1);
        return ;
    }
    int mid = l + r >> 1;
    build(2 * o, l, mid);
    build(2 * o + 1, mid + 1, r);
    update(o);
}

void modify(int o, int l, int r, int L, int R, int x) {

    if(l >= L && r <= R) {
        if(f[o].ma == f[o].mi) {
            if(f[o].ma == x) {
                f[o] = node(f[o].mi + 1, f[o].ma + 1, 1);
                return ;// 如果这个节点合法 就给它升级
            }
            else {
                f[o].tag = 0; return ;//不合法
            }
        }
    }
    int mid = l + r >> 1;
    if(f[o].ma == f[o].mi) f[2 * o].mi = f[2 * o].ma = f[2 * o + 1].ma = f[2 * o + 1].mi = f[o].ma;
    //下放标记 如果我之前访问到这里直接return 现在儿子未作修改 就会出问题
    if(L <= mid && f[2 * o].tag) modify(2 * o, l, mid, L, R, x);
    //只有合法我才去走 否则可能被一行的下放标记救活 直接错掉 并且这样才能保证时间复杂度
    if(mid < R && f[2 * o + 1].tag) modify(2 * o + 1, mid + 1, r, L, R, x);
    update(o);
}

void Init( ) {

    scanf("%d%d",& n,& k);
    build(1, 1, n);
    scanf("%d",& t);
    for(int i = 1;i <= t;i ++) {
        int l, r, k;
        scanf("%d%d%d",& l, & r, & k);
        modify(1, 1, n, l, r, k - 1);
    }
}

void dfs(int o, int l, int r) {

    if(l == r) {
        if(f[o].ma == k) ans ++;
        return ;
    }
    int mid = l + r >> 1;
    if(f[2 * o].tag) {
        if(f[o].mi == f[o].ma) {
            f[2 * o].mi = f[2 * o].ma = f[o].mi;
        }//一边走一边下放标记
        dfs(2 * o, l, mid);
    }
    if(f[2 * o + 1].tag) {
        if(f[o].mi == f[o].ma) {
            f[2 * o + 1].mi = f[2 * o + 1].ma = f[o].ma;
        }
        dfs(2 * o + 1, mid + 1, r);
    }
}

int main( ) {

    freopen("deco.in","r",stdin);
    freopen("deco.out","w",stdout);
    Init( );
    dfs(1, 1, n);
    printf("%d\n",ans);
}

原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9747802.html

时间: 2024-07-30 20:06:55

18.10.6 考试总结的相关文章

18.10.17 考试总结

今天心态崩崩,,,.. 这道题比较简单 因为每一位是单独对答案产生贡献的 所以枚举每一位 用数位dp求出该位是$1$的数量 在求出该位是$0$的 那么答案就是那一位对应的二的幂次再乘以$num1 * num0 * 2$ 每一对会产生两次贡献 代码 #include <bits/stdc++.h> #define rg register #define il inline using namespace std; typedef long long ll; const ll MOD = 1e9

18.10.22 考试总结

我真的我要被我自己给猪死了md T1让输出边长我输出面积硬生生掉了100分 气死 这道题我之前在讲单调栈的时候是讲过的 对于每一个位置 维护一个他的$up$表示以这里为起点只走$1$向上走的高度 然后对于每一行都跑一边求最大矩形的单调栈即可 维护一个单增的 每次弹栈的时候求出以弹栈元素为矩形边长的最大矩形面积 不过这道题是求最大正方形 就改成边长取$min$再取$max$即可 代码 #include <bits/stdc++.h> #define il inline #define rg re

18.10.4 考试总结

这道题就是一道肥!肠!裸!的!轮廓线dp 然后因为细节太多了还因为有一个sbsbsb编译错误 就是不准我函数名字取count...我恨 我永远讨厌轮廓线dp 代码 #include <bits/stdc++.h> using namespace std; const int N = 1e6 + 5; int dp[2][N],n,m,len[200],cnt[N],ans; char s[200][40]; void Init( ) { scanf("%d%d",&

[CareerCup] 18.10 Word Transform 单词转换

18.10 Given two words of equal length that are in a dictionary, write a method to transform one word into another word by changing only one letter at a time. The new word you get in each step must be in the dictionary. 这道题让我们将一个单词转换成另一个单词,每次只能改变一个字母,

18.6 负载均衡集群介绍;18.7 LVS介绍;18.9 LVS NAT模式搭建(上);18.10 LVS NAT模式搭建(下)

扩展: lvs 三种模式详解 http://www.it165.net/admin/html/201401/2248.html lvs几种算法 http://www.aminglinux.com/bbs/thread-7407-1-1.html 关于arp_ignore和 arp_announce http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html lvs原理相关的   http://blog.csdn.net/pi9nc/

18.6 负载均衡集群介绍 18.7 LVS介绍 18.8 LVS调度算法 18.9/18.10 L

18.6 负载均衡集群介绍18.7 LVS介绍 18.8 LVS调度算法 18.9/18.10 LVS NAT模式搭建 原文地址:http://blog.51cto.com/13227377/2149682

#10.4考试总结

10.4考试总结 P1017 进制转换 题目里的进制转换跟最开始做的区别就是这个权值是负数......在短除过程中可能会有各种问题..... 我想用短除就必须要解决这个负数的问题:-3/-2=2 要做到这个样子.....系统从来不会让你好过:-3%-2=-1,总会为难你一下.就需要自己想办法来解决这个问题 -m+n%m 这个样子就可以解决了.....然后题目就简单了起来.栈储存结果,或者递归输出随意就好 P1004 方格取数 没有仔细看数据范围.在认证研读了一边以后.....这.....(哔~~

#10.6考试总结

10.6考试总结 P1063 能量项链 其实是一道区间DP题.......应该并不难.就是DP做少了? 莫名不会.实际上仔细想一想就明白了.直接枚举分段点进行计算就可以了. for(int l = 1, r = x; r < n2; ++l, ++r) { for(int k = l; k < r; ++k) { f[l][r] = max_(f[l][r], f[l][k] + f[k + 1][r] + num[l] * num[r + 1] * num[k + 1]); } if(x =

10.11考试总结

10.11考试总结 全是DP实际上发现暴力也能有部分分....... 三角形牧场 DP......当时总是感觉不像啊 需要处理的就是枚举三角形边长可能出现的情况.因为周长在输入端时候就可以确定了,所以只需要通过枚举两条边就可以强行算出第三条边..... 所以就省空间+时间.... f[0][0] = 1; for (int i=1; i<=n; ++i) for(int j=half; j>=0; j--) for(int k=j; k>=0; k--) if(j >= d[i]