《Codeforces Global Round 16》

A:

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tu;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

void solve() { 
    int n,s;n = read(),s = read();
        int hf = n / 2 + 1;
        int ans = s / hf;
        printf("%d
",ans);
} 
int main() {    
    int ca;ca = read();
    while(ca--) {
        solve();
    }
   // system("pause");
    return 0;
}
View Code

B:

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tu;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

void solve() { 
    string s;cin >> s;
    int len = 0,ans = 0;
    for(auto v : s) {
        if(v == '1') {
            if(len != 0) ans++;
            len = 0;
        }
        else len++;
    }
    if(len != 0) ans++;
    ans = min(ans,2);
    printf("%d
",ans);
} 
int main() {    
    int ca;ca = read();
    while(ca--) {
        solve();
    }
   // system("pause");
    return 0;
}
View Code

C:

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

void solve() {
    int n;n = read();
    string a,b;
    cin >> a >> b;
    int f0 = 0,f1 = 0;
    int ans = 0;
    for(auto v : a) {
        if(v - '0' == 0) f0 = 1;
        else f1 = 1;
    }
    for(auto v : b) {
        if(v - '0' == 0) f0 = 1;
        else f1 = 1;
    }
    for(int i = 0;i < n;++i) {
        if(a[i] == '0' && b[i] == '1' || a[i] == '1' && b[i] == '0') ans += 2;
        else if(a[i] == '0' && b[i] == '0') {
            if(i == n - 1) ans += 1;
            else {
                if(a[i + 1] == '1' && b[i + 1] == '1') ans += 2,++i;
                else ans++;
            }
        }
        else if(a[i] == '1' && b[i] == '1') {
            if(i < n - 1 && a[i + 1] == '0' && b[i + 1] == '0') ans += 2,++i;
        }
    }
    if(f1 == 1 && f0 == 1) ans = max(ans,2);
    printf("%d
",ans);
}
int main() {
    int ca;ca = read();
    while(ca--) {
        solve();
    }
    return 0;
}
View Code

D1:因为只有一行,所以排序后的位置就是他们固定的位置。

比较特殊的地方就是连续相同的处理,很显然我们先放位置最后面的更优。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

int a[N];
vector<int> vec;
void solve() {
    vec.clear();
    int n,m;n = read(),m = read();
    for(int i = 1;i <= n * m;++i) a[i] = read();
    LL ans = 0;
    for(int i = 1;i <= n * m;++i) {
        if(vec.size() == 0) ans += 0;
        else {
            int pos = lower_bound(vec.begin(),vec.end(),a[i]) - vec.begin();
            if(pos != 0) ans += pos;
        }
        vec.push_back(a[i]);
        sort(vec.begin(),vec.end());
    }
    printf("%lld
",ans);


}
int main() {
    int ca;ca = read();
    while(ca--) {
        solve();
    }
    return 0;
}
View Code

D2:也是类似的,这里只有一点不同,那就是对于连续的位置,我们先放位置最前面的更优。因为这样可以保证其他的前面的包含的尽量少。

线段树查询一下就行。这里写的树状数组

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

int a[N],b[N],c[N],tot[N],sum[N],n,m;
vector<int> vec[N];
int lowbit(int x) {return x & (-x);}
void add(int x) {
    for(int i = x;i <= n * m;i += lowbit(i)) sum[i]++;
}
int query(int x) {
    int ans = 0;
    for(int i = x;i;i -= lowbit(i)) ans += sum[i];
    return ans;
}
int query2(int L,int r) {
    return query(r) - query(L - 1);
}
int cal(int pos) {
    int L;
    if(pos % m == 0) L = pos / m - 1;
    else L = pos / m;
    return L;
}
void solve() {
    n = read(),m = read();
    for(int i = 1;i <= n * m;++i) a[i] = read(),b[i] = a[i],sum[i] = 0,c[i] = a[i];
    sort(c + 1,c + n * m + 1);
    sort(b + 1,b + n * m + 1);
    int len = unique(b + 1,b + n * m + 1) - b - 1;
    for(int i = 1;i <= len;++i) vec[i].clear(),tot[i] = 0;
    LL ans = 0;
    for(int i = 1;i <= n * m;++i) {
        int x = lower_bound(b + 1,b + len + 1,c[i]) - b;
        vec[x].push_back(i);
    }
    for(int i = 1;i <= n * m;++i) {
        int x = lower_bound(b + 1,b + len + 1,a[i]) - b;
        int pos = vec[x][tot[x]++],L;
        int c1 = cal(pos);
        int c2 = cal(vec[x][0]);
        if(c1 == c2) {
            int L = c2 * m + 1;
            if(vec[x][0] > L) ans += query2(L,vec[x][0] - 1);
        }
        add(pos);
    }
    printf("%lld
",ans);
}
int main() {
    int ca;ca = read();
    while(ca--) {
        solve();
    }
    return 0;
}
View Code

E:一开始想的挺对的,不管怎么拼接,bud的拆除方式都不会改变。

那么每个bud的贡献就是leaves - 1.

但是我一开始只考虑到了初始是bud的情况,但是在删去一些bud之后会出现新的bud,这也要算上。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

vector<int> G[N];
int ans;
int dfs(int u,int fa) {
    int sum = 0;
    for(auto v : G[u]) {
        if(v == fa) continue;
        sum += dfs(v,u);
    }
    if(sum == 0) return 1;//一开始是叶子或者子节点被删完
    else {
        ans += sum - 1;
        return 0;
    }
}
void solve() {
    int n;n = read();
    for(int i = 1;i <= n;++i) G[i].clear();
    ans = 0;
    for(int i = 1;i < n;++i) {
        int u,v;u = read(),v = read();
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1,0);
    printf("%d
",ans + 1);
}
int main() {
    int ca;ca = read();
    while(ca--) {
        solve();
    }
   // system("pause");
    return 0;
}
View Code

F:一开始理解错题意了。这题是只要碰到线段上的某个点就算到过了。

然后就有两种情况:

1:线段上本来就有点,那就可以删去这条线段。

2:线段里有更小的线段(完全包含)。那大的可以删掉,因为到小的大的也肯定到,到大的小的不一定到。

然后现在就是一种关于点和线段的排列p1 [L1,r1] [L2,r2] ...p2 ....p3..

考虑dp[i][0] - 点i移动完前面所有点后回到原位的最小步数。dp[i][1] - 不回到原位。

转移:对于不回到原的点,我们不能知道它在哪个位置,但是我们可以看成(处理完右边回到原位) + 不回到原位的代价 = 在原位向左不回到原位。

struct用long long就T了。需要用int

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 2e4 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

LL a[N];
struct Node{int L,r;};
LL dp[N][2],vecL[N],vecr[N];//0 - 回到原位置,1 - 不回到原位置.
bool cmp(Node a,Node b) {
    if(a.L != b.L) return a.L < b.L;
    else return a.r > b.r;
}
vector<Node> v;
void solve() {
    int n,m;n = read(),m = read();
    for(int i = 1;i <= n;++i) scanf("%lld",&a[i]);
    sort(a + 1,a + n + 1);
    v.clear();
    for(int i = 1;i <= m;++i) {
        int L,r;L = read(),r = read();
        int pos = lower_bound(a + 1,a + n + 1,L) - a;
        if(pos == n + 1 || a[pos] > r) v.push_back(Node{L,r});
    }
    sort(v.begin(),v.end(),cmp);
    for(int i = 0;i < v.size();++i) {
        if(i != 0 && v[i].r <= v[i - 1].r) {
            v.erase(v.begin() + i - 1);
            i -= 2;
        }
    }
    int now = 0;
    for(int i = 1;i <= n + 1;++i) dp[i][0] = dp[i][1] = INF;
    dp[0][0] = dp[0][1] = 0;
    a[0] = -1e18;
    a[n + 1] = 1e18;
    for(int i = 1;i <= n + 1;++i) {
        int cnt0 = 0,cnt1 = 0;
        vecL[++cnt0] = a[i - 1];
        while(now < v.size() && v[now].r < a[i]) {
            vecL[++cnt0] = v[now].L;
            vecr[++cnt1] = v[now++].r;
        }
        vecr[++cnt1] = a[i];
        for(int j = 1;j <= cnt0;++j) {
            dp[i][0] = min(dp[i][0],dp[i - 1][0] + (vecL[j] - a[i - 1]) + 2LL * (a[i] - vecr[j]));
            dp[i][1] = min(dp[i][1],dp[i - 1][0] + (vecL[j] - a[i - 1]) + (a[i] - vecr[j]));
            dp[i][0] = min(dp[i][0],dp[i - 1][1] + 2LL * (vecL[j] - a[i - 1]) + 2LL * (a[i] - vecr[j]));
            dp[i][1] = min(dp[i][1],dp[i - 1][1] + 2LL * (vecL[j] - a[i - 1]) + (a[i] - vecr[j]));
        }
      //  printf("dp[%d][0] is %lld dp[%d][1] is %lld
",i,dp[i][0],i,dp[i][1]);
    }
    printf("%lld
",min(dp[n + 1][0],dp[n + 1][1]));
}
int main() {
    int ca;ca = read();
    while(ca--) {
        solve();
    }
  //  system("pause");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zwjzwj/p/15318659.html