zoukankan      html  css  js  c++  java
  • 【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('
    ')
    #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('
    ')
    #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('
    ')
    #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('
    ')
    #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('
    ')
    #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('
    ')
    #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();
    }
    
  • 相关阅读:
    template(2.2)
    Filter过滤链条
    The 3n + 1 problem
    Struts2.3+Spring4.0
    康托展开
    templates(2.1)
    templates(1.2)
    templates(1.1)
    我和你
    Android 的上下文菜单: Context Menu
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10746606.html
Copyright © 2011-2022 走看看