codeforces1217-edu

C The Number Of Good Substrings

我原来的基本思路也是这样,但是写的不够好

注意算前缀和的时候,字符串起始最好从1开始。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+10;
string s;
int lst[maxn];

int main(){
    ios::sync_with_stdio(false);
    int  _;
    cin>>_;
    while(_--){
        cin>>s;
        int pos = 0;
        int len = s.length();
        s = '#'+s;
        for(int i=1; i<=len; i++){
            if(s[i] == '1'){
                lst[i] = pos;
                pos = i;
            }
        }
        int ans = 0;
        for(int i=1; i<=len; i++){
            int num = 0;
            if(s[i] == '1')
                //最多移动18次
                for(int j=i; j<=len; j++){
                    num = num*2+s[j]-'0';
                    if(num>j-lst[i]) break;
                    //cout<<i<<" "<<lst[i]+1<<" "<<j<<endl;
                    ans ++;
                }
            }
        }
        cout<<ans<<endl;
    }

    return 0;
}

D 有向图的环问题 Coloring Edges

给有向图的每一条边染色,使得不存在一个环,使得所有的边的颜色相同。

问最少的颜色数。

答案最大为2,然后判断是否存在有向环就可以了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 5000+10;
struct Edge{
    int v, id;
};
vector<Edge> G[maxn];
int n, m;
int res = 1;
int col[maxn];
int vis[maxn];

void dfs(int u){
    vis[u] = 1;
    for(int i=0; i<G[u].size(); i++){
        int v = G[u][i].v;
        int id = G[u][i].id;
        if(vis[v] == 0) dfs(v);
        else if(vis[v] == 1) {
            res=2;
            col[id]=2;
        }
    }
    vis[u] = 2;
}

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    int u, v;
    for(int i=1; i<=m; i++){
        cin>>u>>v;
        G[u].push_back(Edge{v, i});
        col[i] = 1;
    }
    for(int i=1; i<=n; i++){
        if(!vis[i]) dfs(i);
    }
    cout<<res<<endl;
    for(int i=1; i<m; i++) cout<<col[i]<<" ";
    cout<<col[m]<<endl;

    return 0;
}

E 线段树 Sum Queries?

维护每一个数的每一位

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
#define lc (rt<<1)
#define rc (rt<<1|1)
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+10;


int n, m, k;

struct node{
    int val[9][2];

    void init(){memset(val,0x3f,sizeof(val));}

    void get(int x){
        init();
        int t=x;
        for(int i=0;i<9;i++){
            //若某一位有两个不为0,则一定unbalance.
            if(t%10) val[i][0]=x;
            t/=10;
        }
    }

    void print(){
        for(int i=0;i<9;i++){
            printf("%d: %d %d
",i,val[i][0],val[i][1]);
        }
        printf("
");
    }
};
//只要有两个数,某一位上面的模数不为0,则一定是unblanced.

void merge(node &b, node& c){
    for(int i=0;i<9;i++){
        for(int j=0;j<2;j++){
            int t=b.val[i][j];
            for(int k=0;k<2;k++){
                if(t < c.val[i][k]) swap(t,c.val[i][k]);
            }
        }
    }
}

int a[maxn];

node tree[4*maxn];

void pushup(int rt, int l, int r){
    if(l == r){

        tree[rt].get(a[l]);
        return ;
    }
    else{
        memcpy(tree[rt].val,tree[lc].val,sizeof(tree[lc].val));
        merge(tree[rc],tree[rt]);
    }
}

void build(int rt, int l, int r){
    if(l < r){
        int M = l + (r - l)/2;
        build(lc,l,M); build(rc,M+1,r);
    }
    pushup(rt, l, r);
}

void update(int rt ,int l, int r, int pos){
    if(l < r){
        int M = l + (r - l)/2;
        if(pos<=M) update(lc,l,M,pos);
        else update(rc,M+1,r,pos);
    }
    pushup(rt,l,r);
}

node e; int ql, qr;

void query(int rt, int l, int r){
    if(ql <= l && qr >= r){
        //cout<<233<<endl;
        //tree[rt].print();
        merge(tree[rt],e);
        return;
    }
    else{
        int M = l + (r - l)/2;
        if(ql<=M) query(lc,l,M);
        if(qr>=M+1) query(rc,M+1,r);
    }
}

int main(){
    while(~scanf("%d%d", &n, &m)){
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);

        build(1,1,n);
        while(m--){
            int op; scanf("%d",&op);
            if(op==1){
                int pos; scanf("%d",&pos);
                scanf("%d",&a[pos]);
                update(1,1,n,pos);
            }
            else{
                scanf("%d %d",&ql,&qr);
                e.init(); query(1,1,n);
                //e.print();
                int ans = -1;
                for(int i=0;i<9;i++){
                    if(e.val[i][1] == inf) continue;
                    int t = e.val[i][0] + e.val[i][1];
                    if(ans == -1 || ans > t) ans = t;
                }
                printf("%d
",ans);
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/babydragon/p/11473669.html