codeforces-1136 (div2)

A.读到第i章,就有N - i + 1章还没读。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
PII a[maxn];
int main(){
    Sca(N);
    for(int i = 1; i <= N ; i ++){
        Sca2(a[i].fi,a[i].se);
    }
    K = read();
    for(int i = 1; i <= N ; i ++){
        if(a[i].fi <= K && K <= a[i].se){
            Pri(N - i + 1);
            break;
        }
    }
    return 0;
}
View Code

B.很显然,先把起始点的石头扔到一边,然后向离端点距离短的一边走,走到端点再想另一端走,途中一边取硬币,石头全扔到起始点。

推出式子显然

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
PII a[maxn];
int main(){
    Sca2(N,K);
    Pri(2 + N + 2 * min(N - K,K - 1) + max(N - K,K - 1) + N - 1);
    return 0;
}
View Code

C.发现对2 * 2的矩阵操作就是把斜相邻的两个数交换,其余N * M的矩阵操作都可以通过交换两个斜对角实现,所以交换只能交换左上右下这样一个斜对角。

那么判断两个矩阵的每个斜对角是否是相同的元素即可

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 510;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int A[maxn][maxn],B[maxn][maxn];
vector<int>a[maxn * 2],b[maxn * 2];
int main(){
    Sca2(N,M);
    For(i,1,N) For(j,1,M) Sca(A[i][j]);
    For(i,1,N) For(j,1,M) Sca(B[i][j]);
    For(i,1,N) For(j,1,M){
        a[i + j].pb(A[i][j]);
        b[i + j].pb(B[i][j]);
    }
    for(int i = 1; i <= N + M ; i ++){
        sort(a[i].begin(),a[i].end());
        sort(b[i].begin(),b[i].end());
        if(a[i] != b[i]){
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    return 0;
}
View Code

D.前面的u点可以和后面的v点交换称为u可以吃掉v,点i最终可以排到nastya的后面需要满足在他后面的点是自主排到nastya后面或者它可以被i吃掉。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 3e5 + 10;
const int maxm = 5e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int a[maxn];
int pos[maxn];
int pre[maxn];
struct Edge{
    int to,next;
}edge[maxm * 2];
int head[maxn],tot;
void init(){
    for(int i = 0 ; i <= N ; i ++) head[i] = -1;
    tot = 0;
}
void add(int u,int v){
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}
int main(){
    Sca2(N,M); init();
    for(int i = 1; i <= N ; i ++){
        a[i] = read();
        pos[a[i]] = i;
    }
    for(int i = 1; i <= M ; i ++){
        PII e; e.fi = read(); e.se = read();
        if(pos[e.fi] < pos[e.se]){
            pre[pos[e.fi]]++;
            add(pos[e.se],pos[e.fi]);
        } 
    }
    int ans = 0,now = 1;
    for(int i = N - 1; i >= 1; i --){
        if(pre[i] == now){
            ans++;
            for(int j = head[i]; ~j ; j = edge[j].next) pre[edge[j].to]--;
        }else{
            now++;
        }
    }
    Pri(ans);
    return 0;
}
D

E.对k求一个前缀和pre,对于u点,属于[u,N]之间的所有点i的最小值都会满足 a[x] >= a[u] + pre[i] - pre[u]

对于i来说,pre[i]是固定的,动态更新的是a[u] - pre[u],所以将pre[i]分离出来,线段树维护每个点的a[u] - pre[u],维护区间和以及最大最小值。

求区间和的时候就是ppre[r] - ppre[l - 1] + 线段树维护的l到r之间的和。

坑点:lazy标记不能打成0,需要设为-INF,因为a[u] - pre[u]可能是负数

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
LL read(){LL x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 1e5 + 10;
const LL INF = 1e18;
const int mod = 1e9 + 7; 
int N,M,K;
struct Tree{
    int l,r;
    LL sum,MIN,MAX,lazy;
}tree[maxn << 2];
LL a[maxn],pre[maxn],ppre[maxn];
void Pushup(int t){
    tree[t].sum = tree[t << 1].sum + tree[t << 1 | 1].sum;
    tree[t].MIN = min(tree[t << 1].MIN,tree[t << 1 | 1].MIN);
    tree[t].MAX = max(tree[t << 1].MAX,tree[t << 1 | 1].MAX);
}
void Build(int t,int l,int r){
    tree[t].l = l; tree[t].r = r;
    tree[t].lazy = -INF;
    if(l == r){
        tree[t].MAX = tree[t].sum = tree[t].MIN = a[l] - pre[l];
        return;
    }
    int m = l + r >> 1;
    Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);
    Pushup(t);
}
void change(int t,LL p){
    tree[t].lazy = max(p,tree[t].lazy);
    tree[t].sum = (tree[t].r - tree[t].l + 1) * p;
    tree[t].MAX = tree[t].MIN = p;
}
void Pushdown(int t){
    if(tree[t].lazy != -INF){
        change(t << 1,tree[t].lazy); change(t << 1 | 1,tree[t].lazy);
        tree[t].lazy = -INF;
    }
}
void update(int t,int l,int r,LL p){
    if(tree[t].MIN >= p) return;
    if(l <= tree[t].l && tree[t].r <= r && tree[t].MAX <= p){
        change(t,p);
        return;
    }
    Pushdown(t);
    int m = (tree[t].r + tree[t].l) >> 1;
    if(r <= m) update(t << 1,l,r,p);
    else if(l > m) update(t << 1 | 1,l,r,p);
    else{
         update(t << 1,l,m,p); 
         update(t << 1 | 1,m + 1,r,p);
    }
    Pushup(t);
}
LL query(int t,int l,int r){
    if(l <= tree[t].l && tree[t].r <= r) return tree[t].sum;
    Pushdown(t);
    int m = (tree[t].l + tree[t].r) >> 1;
    if(r <= m) return query(t << 1,l,r);
    else if(l > m) return query(t << 1 | 1,l,r);
    else return query(t << 1,l,m) + query(t << 1 | 1,m + 1,r);    
}
int main(){
    Sca(N);
    for(int i = 1; i <= N ; i ++) a[i] = read();
    for(int i = 2; i <= N; i ++){
        pre[i] = read() + pre[i - 1];
        ppre[i] = pre[i] + ppre[i - 1];
    }
    Build(1,1,N);
    int Q; Sca(Q);
    while(Q--){
        char op[3]; int l,r;
        scanf("%s%d%d",&op,&l,&r);
        if(op[0] == '+'){
            LL x = query(1,l,l) + r + pre[l];
            update(1,l,N,x - pre[l]);
        }else{
            Prl(query(1,l,r) + ppre[r] - ppre[l - 1]);
        }
    }
    return 0;
}
E
原文地址:https://www.cnblogs.com/Hugh-Locke/p/10692106.html