【AtCoder】AGC013

AGC013

A - Sorted Arrays

直接分就行

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int a[MAXN];
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) read(a[i]);
    int f = 0;
    int ans = N;
    for(int i = 2 ; i <= N ; ++i) {
    if(!f) {
        if(a[i] > a[i - 1]) f = 1;
        else if(a[i] < a[i - 1]) f = -1;
        --ans;
    }
    else {
        if(a[i] > a[i - 1] && f == 1) --ans;
        else if(a[i] < a[i - 1] && f == -1) --ans;
        else if(a[i] == a[i - 1]) --ans;
        else f = 0;
    }
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

B - Hamiltonish Path

直接一条路扩展到不能扩展位置

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
struct node {
    int to,next;
}E[MAXN * 2];
int N,M,head[MAXN],sumE;
int que[MAXN * 2],ql,qr;
bool vis[MAXN];
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void Solve() {
    read(N);read(M);
    int a,b;
    for(int i = 1 ; i <= M ; ++i) {
    read(a);read(b);
    add(a,b);add(b,a);
    }
    ql = N,qr = N - 1;
    que[++qr] = 1;vis[1] = 1;
    while(1) {
    int u = que[qr];
    bool flag = 1;
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(!vis[v]) {
        que[++qr] = v;
        vis[v] = 1;
        flag = 0;break;
        }
    }
    if(flag) break;
    }
    while(1) {
    int u = que[ql];
    bool flag = 1;
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(!vis[v]) {
        que[--ql] = v;
        vis[v] = 1;
        flag = 0;break;
        }
    }
    if(flag) break;
    }
    out(qr - ql + 1);enter;
    for(int i = ql ; i <= qr ; ++i) {
    out(que[i]);space;
    }
    enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

C - Ants on a Circle

显然可以求出所有蚂蚁最后的位置,现在要确定第一个人的位置

逆时针转,撞一下编号减一,顺时针转,撞一下编号加一,模拟一下即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int64 T,x[MAXN],to[MAXN],ans[MAXN],L;
int id[MAXN],w[MAXN];
void Solve() {
    read(N);read(L);read(T);
    for(int i = 0 ; i < N ; ++i) {
    read(x[i]);read(w[i]);
    if(w[i] == 1) to[i] = (x[i] + T) % L;
    else to[i] = ((x[i] - T) % L + L) % L;
    id[i] = i;
    }
    sort(id,id + N,[](int a,int b){return to[a] < to[b] || (to[a] == to[b] && w[a] < w[b]);});
    int pos = 0;
    for(int i = 1 ; i < N ; ++i) {
    if(w[i] ^ w[0]) {
        pos += (T / L) * 2 % N;
        int64 rem = T % L;
        int64 dis = x[i] - x[0];
        if(w[0] == 2) dis = L - dis;
        if(dis + L < 2 * rem) pos += 2;
        else if(dis < 2 * rem) pos += 1;
        pos %= N;
    }
    }
    if(w[0] == 1) pos %= N;
    else pos = (N - pos % N) % N;
    for(int i = 0 ; i < N ; ++i) {
    if(id[i] == 0) {
        int p = i;
        int cnt = 0;
        while(cnt < N) {
        ans[pos] = to[id[p]];
        p = (p + 1) % N;
        pos = (pos + 1) % N;
        ++cnt;
        }
    }
    }
    for(int i = 0 ; i < N ; ++i) {
    out(ans[i]);enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

D - Piling Up

假如现在盒子里有\(x\)个红球,\(N - x\)个蓝球

\(dp[i][x]\)表示前\(2i\)个放完之后盒子里有\(x\)个红球

然后有四种

\(RR\),要求\(x > 0\),然后x - 1

\(RB\),要求\(x > 0\),然后x不变

\(BB\),要求\(x < N\),然后x + 1

\(BR\),要求\(x < N\),然后x不变

为了不重复统计,可以直接设置一个临近底部的特殊标记,如果这个操作序列画出的x变化图像不能下移才记录

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int MOD = 1000000007;
int dp[3005][3005][2];
int N,M;
int inc(int a,int b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
    return 1LL * a * b % MOD;
}
void update(int &x,int y) {
    x = inc(x,y);
}
void Solve() {
    read(N);read(M);
    for(int i = 0 ; i <= N ; ++i) dp[0][i][0] = 1;
    for(int i = 0 ; i < M ; ++i) {
    for(int j = 0 ; j <= N ; ++j) {
        for(int k = 0 ; k <= 1 ; ++k) {
        if(!dp[i][j][k]) continue;
        if(j >= 1) {
            int t = 0;
            if(j == 1) t = 1;
            update(dp[i + 1][j - 1][k | t],dp[i][j][k]);
            update(dp[i + 1][j][k | t],dp[i][j][k]);
        }
        if(j <= N - 1) {
            int t = 0;
            if(j == 0) t = 1;
            update(dp[i + 1][j + 1][k | t],dp[i][j][k]);
            update(dp[i + 1][j][k | t],dp[i][j][k]);
        }
        }
    }
    }
    int ans = 0;
    for(int j = 0 ; j <= N ; ++j) update(ans,dp[M][j][1]);
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

E - Placing Squares

平方和转有序对

直接统计\(dp[x][i = 0,1,2]\)为从上一个端点开始选了几个点的方案

可以矩阵乘法,特殊端点处停下即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}

int MOD = 1000000007;
int inc(int a,int b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
    return 1LL * a * b % MOD;
}
void update(int &x,int y) {
    x = inc(x,y);
}
struct Matrix {
    int f[3][3];
    Matrix() {memset(f,0,sizeof(f));}
    friend Matrix operator * (const Matrix &a,const Matrix &b) {
    Matrix c;
    for(int i = 0 ; i < 3 ; ++i) {
        for(int j = 0 ; j < 3 ; ++j) {
        for(int k = 0 ; k < 3 ; ++k) {
            update(c.f[i][j],mul(a.f[i][k],b.f[k][j]));
        }
        }
    }
    return c;
    }
    void unit() {
    for(int i = 0 ; i < 3 ; ++i) f[i][i] = 1;
    }
}A,B,ans;
int N,M,x[MAXN];
Matrix fpow(Matrix a,int c) {
    Matrix res,t = a;
    res.unit();
    while(c) {
    if(c & 1) res = res * t;
    t = t * t;
    c >>= 1;
    }
    return res;
}
void Solve() {
    read(N);read(M);
    ans.unit();
    A.f[0][1] = 2;A.f[0][2] = 1;A.f[0][0] = 1;
    A.f[1][2] = 1;A.f[1][1] = 1;
    A.f[2][2] = 2;A.f[2][0] = 1;A.f[2][1] = 2;
    B = A;B.f[2][0] = 0;B.f[2][1] = 0;B.f[2][2] = 1;
    int p = 0;
    for(int i = 1 ; i <= M ; ++i) {
    read(x[i]);
    ans = ans * fpow(A,x[i] - p);
    ans = ans * B;
    p = x[i] + 1;
    }
    ans = ans * fpow(A,N - p);
    out(ans.f[0][2]);enter;
    
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

F - Two Faced Cards

离散化之后把\([C[i],tot]\)减1

然后把正面的\([A[i],tot]\)加1

然后序列中不能有小于0的数,因为我们最后还能加上一张卡,在这之前我们需要满足所有的负值大于等于-1

我们从后往前扫不合法的负值,然后配上一个覆盖这个点左端点最小的区间,这个一定要从右往左做,因为之后给了一张牌是能覆盖一个后缀区间,之后的前缀区间需要另外的操作,我们希望我们把这个负值合法化的同时,前面的负值处理的最多

之后就是前缀区间需要补充的操作,对于每个遇到负值元素选当前覆盖它的区间右端点最大的区间即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N,Q,pos;
int A[MAXN][2],C[MAXN],ans;
int val[MAXN * 4],tot;
int cnt[MAXN * 4],num[MAXN * 4],f[MAXN * 4],inx[MAXN * 4];
bool all_fail;
struct cmp1 {
    bool operator () (pii a,pii b) {
    if(a.fi != b.fi) return a.fi < b.fi;
    return a.se > b.se;
    }
};
struct cmp2 {
    bool operator () (pii a,pii b) {
    if(a.se != b.se) return a.se > b.se;
    return a.fi < b.fi;
    }
};
multiset<pii,cmp1> S1;
multiset<pii,cmp2> S2;
vector<int> v[MAXN * 4];
vector<pii > rec;
void Init() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) {
    read(A[i][0]);read(A[i][1]);
    val[++tot] = A[i][0];
    val[++tot] = A[i][1];
    }
    for(int i = 1 ; i <= N + 1 ; ++i) {
    read(C[i]);
    val[++tot] = C[i];
    }
    sort(val + 1,val + tot + 1);
    tot = unique(val + 1,val + tot + 1) - val - 1;
    for(int i = 1 ; i <= N ; ++i) {
    int t = lower_bound(val + 1,val + tot + 1,A[i][0]) - val;
    cnt[t]++;
    }
    for(int i = 1 ; i <= N + 1 ; ++i) {
    int t = lower_bound(val + 1,val + tot + 1,C[i]) - val;
    cnt[t]--;
    }
    for(int i = 1 ; i <= tot ; ++i) {
    num[i] = cnt[i];
    cnt[i] += cnt[i - 1];
    }
    ans = N;
    for(int i = 1 ; i <= N ; ++i) {
    if(A[i][0] > A[i][1]) {
        int s = lower_bound(val + 1,val + tot + 1,A[i][0]) - val;
        int t = lower_bound(val + 1,val + tot + 1,A[i][1]) - val;
        v[s - 1].pb(t);
    }
    }
    int pre = 0;
    memset(inx,0,sizeof(inx));
    for(int i = tot ; i >= 1 ; --i) {
    for(auto s : v[i]) S1.insert(mp(s,i));
    pre += inx[i];
    cnt[i] += pre;
    while(cnt[i] < -1 && S1.size() > 0) {
        pii seg = *S1.begin();S1.erase(S1.begin());
        if(seg.fi > i) {rec.pb(seg);continue;}
        num[seg.fi]++;num[seg.se + 1]--;
        inx[seg.fi - 1]--;
        --ans;
        cnt[i]++;++pre;
    }
    if(cnt[i] < -1) all_fail = 1;
    }
    for(int i = 1 ; i <= tot ; ++i) {
    num[i] += num[i - 1];
    v[i].clear();
    }
    for(auto t : S1) {
    rec.pb(t);
    }
    for(auto t : rec) {
    v[t.fi].pb(t.se);
    }
    memset(inx,0,sizeof(inx));
    pre = 0;
    for(int i = 1 ; i <= tot ; ++i) {
    for(auto t : v[i]) S2.insert(mp(i,t));
    pre += inx[i];
    num[i] += pre;
    if(num[i] == -1) {
        if(S2.size() <= 0) {
        for(int j = i ; j <= tot ; ++j) f[j] = -1;
        break;
        }
        pii seg = *S2.begin();
        if(seg.se < i) {
        for(int j = i ; j <= tot ; ++j) f[j] = -1;
        break;
        }
        inx[seg.se + 1]--;
        ++pre;
        f[i] = f[i - 1] + 1;
    }
    else f[i] = f[i - 1];
    }
    f[tot + 1] = -1;
}

void Solve() {
    int Q;
    read(Q);
    int d,e;
    for(int i = 1 ; i <= Q ; ++i) {
    read(d);read(e);
    if(all_fail) {puts("-1");continue;}
    int res = -1;
    int t = lower_bound(val + 1,val + tot + 1,d) - val - 1;
    if(val[t - 1] == d - 1) {
        if(f[t - 1] != -1) res = max(ans - f[t - 1] + 1,res);
    }
    if(f[t] != -1) res = max(ans - f[t] + 1,res);
    t = lower_bound(val + 1,val + tot + 1,e) - val - 1;
    if(val[t - 1] == e - 1) {
        if(f[t - 1] != -1) res = max(ans - f[t - 1],res);
    }
    if(f[t] != -1) res = max(ans - f[t],res);
    out(res);enter;
    }
    
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Init();
    Solve();
}

猜你喜欢

转载自www.cnblogs.com/ivorysi/p/10746606.html
今日推荐