Codeforces Round #590 (Div. 3)(有東西)

A 不說了簽到題

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
//freopen("E://oneout.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e6 + 10;
const int maxm = (maxn<<5) + 5;
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int T, n;
int main(){
    scanf("%d", &T);
    while(T --){
        scanf("%d", &n);
        ll ans = 0, x;
        for(int i = 1 ; i <= n ; ++ i){
            scanf("%lld", &x);
            ans += x;
        }
        if(ans % n == 0) cout << ans / n << endl;
        else cout << ans / n + 1 << endl;
    }
    return 0;
}

B1 / B2 Social Network (hard version)

隊列維護, map標記是否在隊列中

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
//freopen("E://oneout.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e6 + 10;
const int maxm = (maxn<<5) + 5;
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int T, n, k, x;
map<int, int> ma;
int deq[maxn];
int main(){
    scanf("%d %d", &n, &k);
    int head = 1, tail = 0;
    for(int i = 1 ; i <= n ; ++ i){
        scanf("%d", &x);
        if(ma[x] == 0){
            deq[++tail] = x;
            ma[x] = 1;
            if(tail - head + 1 > k){
                ma[deq[head]] = 0;
                head ++;
            }
        }
    }
    cout << tail - head + 1 << endl;
    for(int i = tail ; i >= head ; -- i){
        cout << deq[i] << ' ';
    }
    return 0;
}

C Pipes

dfs

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int a[3][maxn];
int book[3][maxn],n,m,flag=0,top=0;
void dfs(int x,int y,int front);
struct note
{
    int x;
    int y;
}s[maxn*2];
int main()
{
    int i,j,num=0, T;
    scanf("%d", &T);
    while(T--){
        scanf("%d",&m);
        n = 2;
        flag = 0, top = 0;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                scanf("%1d",&a[i][j]);
                book[i][j] = 0;
                if(a[i][j]<=2) a[i][j] = 5;
                else a[i][j] = 1;
            }
        }
        dfs(1,1,1);
        if(flag==0)
        {
            printf("NO\n");
        }
        else
        {
            printf("YES\n");
        }
    }
 
    return 0;
}
void dfs(int x,int y,int front)
{
    int i;
    if(flag) return;
    if(x==n&&y==m+1)
    {
        flag=1;
        return ;
    }
    if(x<1||x>n||y<1||y>m)
    {
        return ;
    }
    if(book[x][y]==1)
    {
        return ;
    }
    book[x][y]=1;
 
    //將當前嘗試座標入棧
    top++;
    s[top].x=x;
    s[top].y=y;
 
    if(a[x][y]>=5&&a[x][y]<=6)//當前水管是直管的情況
    {
        if(front==1)
        {
            dfs(x,y+1,1);
        }
        if(front==2)
        {
            dfs(x+1,y,2);
        }
        if(front==3)
        {
            dfs(x,y-1,3);
        }
        if(front==4)
        {
            dfs(x-1,y,4);
        }
    }
    if(a[x][y]>=1&&a[x][y]<=4)//當前水管是彎管的情況
    {
        if(front==1)
        {
            dfs(x+1,y,2);
            dfs(x-1,y,4);
        }
        if(front==2)
        {
            dfs(x,y+1,1);
            dfs(x,y-1,3);
        }
        if(front==3)
        {
            dfs(x-1,y,4);
            dfs(x+1,y,2);
        }
        if(front==4)
        {
            dfs(x,y+1,1);
            dfs(x,y-1,3);
        }
    }
    top--;
    return ;
}

D Distinct Characters Queries

26個樹狀數組每個維護對應字符出現的位置,查詢時對於 l~r判斷區間和是否>0便可知區間內有無此字符

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
#include<tr1/unordered_map>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
//freopen("E://oneout.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
//tr1::unordered_map<int,int>mp;
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e6 + 10;
const int maxm = (maxn<<5) + 5;
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
char s[maxn];
int c[30][maxn];
int n, m;
void update(int pos, int x, int y){
    if(x != -1) for(int i = pos ; i <= n ; i += lowbit(i)) c[x][i] --;
    for(int i = pos ; i <= n ; i += lowbit(i)) c[y][i] ++;
}
ll query(int pos, int x){ ll ans = 0;
    for(int i = pos ; i > 0 ; i -= lowbit(i)) ans += c[x][i];
    return ans;
}
int main(){
    int op, x, y;
    scanf("%s", s + 1);
    scanf("%d", &m);
    n = strlen(s + 1);
    for(int i = 1 ; i <= n ; ++ i){
        update(i, -1, s[i] - 'a' + 1);
    }
    while(m --){
        scanf("%d", &op);
        if(op == 1){
            scanf("%d", &x);
            char z[5];
            scanf("%s", z);
            y = z[0] - 'a' + 1;
            update(x, s[x] - 'a' + 1, y);
            s[x] = z[0];
        }
        else{
            int cnt = 0;
            scanf("%d %d", &x, &y);
            for(int i = 1 ; i <= 26 ; ++ i){
                if(query(y, i)-query(x-1, i)) cnt ++;
            }
            cout << cnt << endl;
        }
    }
    return 0;
}

E Special Permutations

算貢獻, 比如對於X1和X2(x1<x2), 對於[1, X1-1]和[X2+1,n]的貢獻都是x2-x1,對於(x1,x2)的貢獻就是x2-x1-1,對於x1的貢獻是x2-1,對於x2的貢獻是x1 - 1 + 1, 那麼樹狀數組直接維護即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
#include<tr1/unordered_map>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
//freopen("E://oneout.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
//tr1::unordered_map<int,int>mp;
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e6 + 10;
const int maxm = (maxn<<5) + 5;
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int n, m;
int a[maxn];
ll c[maxn];
void update(int x, int k){
    for(int i = x ; i <= n ; i += lowbit(i)) c[i] += k;
}
void add(int l, int r, int k){
    if(l > r) return;
    update(l, k); update(r + 1, -k);
}
ll query(int x){ ll ans = 0;
    for(int i = x; i > 0 ; i -= lowbit(i)) ans += c[i];
    return ans;
}
int main(){
    scanf("%d %d", &n, &m);
    for(int i = 1 ; i <= m ; ++ i){
        scanf("%d", &a[i]);
    }
    for(int i = 1 ; i < m ; ++ i){
        int l = a[i], r = a[i+1];
        if(l == r) continue;
        if(l > r) swap(l, r);
        add(1, l - 1, r - l);
        add(r + 1, n, r - l);
        add(l, l, r - 1);
        add(r, r, l);
        if(l + 1 <= r - 1) add(l + 1, r - 1, r - l - 1);
        //cout << query(n) << endl;
    }
    for(int i = 1 ; i <= n ; ++ i) cout << query(i) << ' ';
    return 0;
}

F Yet Another Substring Reverse

子集dp

i是枚舉的狀態, dp[i]表示對於狀態i,最多出現這些字符(即i二進制上爲1的字符)的最長長度是多少。

比如abcdecdf,(7的二進制是111,即出現的字符是abc,原串中1-3可滿足) 所以dp[7]=3

ans = max(dp[i]+dp[(1<<20)-1-i] ,ans)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
#include<tr1/unordered_map>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
//freopen("E://oneout.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
//tr1::unordered_map<int,int>mp;
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = (1 << 20) + 10;
const int maxm = (maxn<<5) + 5;
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
char s[maxn];
int dp[maxn];
int main(){
    scanf("%s", s + 1);
    int n = strlen(s + 1);
    for(int i = 1 ; i <= n ; ++ i){
        int x = 0;
        for(int j = i ; j <= n ; ++ j){
            int y = s[j] - 'a';
            if(x & (1 << y)) break;//如果x和y有交集,及說明出現重複字符
            x = x ^ (1 << y);//相當於取並集
            dp[x] = j - i + 1;
        }
    }
    for(int i = 0 ; i < 20 ; ++ i)
        for(int j = 0 ; j < (1 << 20) ; ++ j)
            if((j & (1 << i)) == 0)//如果沒有交集
                dp[j ^ (1 << i)] = max(dp[j ^ (1 << i)], dp[j]);
    int ans = 0;
    for(int i = 0 ; i < (1 << 20) ; ++ i){
        ans = max(ans, dp[i] + dp[(1 << 20) - 1 - i]);
    }
    cout << ans;
    return 0;
}

枚舉子集從大到小的方法

int S2, S=22;
void f(int x){
    int k = 0, a[10]={0};
    while(x){
        a[++k] = x % 2;
        x /= 2;
    }
    for(int i = k ; i >= 1 ; -- i) cout << a[i]; cout<<" ";
}
int main(){
    // S是原集合,S1是子集,S2是S1關於S的補集
    for(int S1=S;S1!=0;S1=(S1-1)&S){
        S2=S^S1;
        f(S);f(S1);f(S2);puts("");
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章