Codeforces Round #600 (Div. 2)

A 模拟

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
 
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 1e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
 
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
 
inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
 
ll m_pow(ll x, ll n, ll m) {
    ll res = 1;
    while (n > 0) {
        if (n & 1)
            res = (res * x) % m;
        x = (x * x) % m;
        n >>= 1;
    }
    return res % m;
}
 
int main() {
    int t, a[N], b[N];
    cin >> t;
    while (t--) {
        int n, flag = 0;
        cin >> n;
        rep(i, 1, n) cin >> a[i];
        rep(i, 1, n) cin >> b[i];
        rep(i, 1, n) b[i] = b[i] - a[i];
        int p = 1, q = n;
 
        while (b[p] == 0 && p < q)
            p++;
        while (b[q] == 0 && p < q)
            q--;
 
        if (p <= q) {
            int a0 = b[p];
            rep(i, p , q) {
                if (b[i] != a0 || b[i]<0) {
                    cout << "NO" << endl;
                    flag = 1;
                    break;
                }
            }
        }
        if (!flag) cout << "YES" << endl;
    }
    return 0;
}

B 贪心

#include<stdio.h>
#include<set>
#include<iostream>
#include<stack>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mod = 1e9+7;
 
int mo(ll a, int p) {
    return a >= p ? a % p : a;
}
inline int rd() {
    int x = 0, f = 1;
    char ch;
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return f * x;
}
int n,x;
int a[1000020];
vector<int>v;
vector<int>k;
int cur,cnt;
int main() {
    io_opt;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        k.push_back(x);
        if(x>0){
            if(a[x]==-1||a[x]==1){
                cout<<"-1\n";
                return 0;
            }
            else{
                a[x]=1;
                cur++;
            }
        }
        else{
            if(a[-x]!=1){
                //cout<<a[x]<<endl;
                cout<<"-1\n";
                return 0;
            }
            else{
                a[-x]=-1;
                cur--;
            }
        }
        cnt++;
        if(cur==0){
            v.push_back(cnt);
            cnt=0;
            for(int j=0;j<k.size();j++){
                if(k[j]<0) k[j]=-k[j];
                a[k[j]]=0;
            }
            k.clear();
        }
    }
    if(cur!=0){
        cout<<"-1\n";
        return 0;
    }
    cout<<v.size()<<endl;
    for(int i=0;i<v.size();i++){
        cout<<v[i]<<' ';
    }
    return 0;
}

C 递推
题意是给nn个数,对于前kk小的,求出(a1am)1+(am+1a2m)2(a_1~a_m)*1 + (a_{m+1}~a_{2m})*2
求出前缀和,则fi=fim+i=1naif_i=f_{i-m} + \sum_{i=1}^n a_i

#include<stdio.h>
#include<set>
#include<iostream>
#include<stack>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
typedef long long ll;
typedef long double ld;
typedef double db;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int mod = 1e9+7;

int mo(ll a, int p) {
   return a >= p ? a % p : a;
}
inline int rd() {
   int x = 0, f = 1;
   char ch;
   while (ch < '0' || ch > '9') {
       if (ch == '-')f = -1;
       ch = getchar();
   }
   while (ch >= '0' && ch <= '9') {
       x = x * 10 + ch - '0';
       ch = getchar();
   }
   return f * x;
}
ll n,m;
ll a[200020],ans[200020];
int main() {
   io_opt;
   cin>>n>>m;
   for(int i=1;i<=n;i++){
       cin>>a[i];
   }
   sort(a+1,a+1+n);
   for(int i=1;i<=n;i++){
       a[i]+=a[i-1];
   }
   for(int i=1;i<m;i++){
       ans[i]=a[i];
   }
   for(int i=m;i<=n;i++){
       ans[i]=ans[i-m]+a[i];
   }
   for(int i=1;i<=n;i++){
       cout<<ans[i]<<' ';
   }
   return 0;
}

D dfs+贪心

要求求出最少添加多少条边,可以使给出的图满足对于每个uu,序号为1u11~u-1的点都uu连通。
dfs出联通块,按照每个联通块中序号最小的点排序;从前向后做,如果当前所有的最大序号大于下一个的最小序号,则加边,同时更新最大值。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>

#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 2e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

inline ll read() {
   ll x = 0, f = 1;
   char ch = getchar();
   while (ch < '0' || ch > '9') {
       if (ch == '-')f = -1;
       ch = getchar();
   }
   while (ch >= '0' && ch <= '9') {
       x = x * 10 + ch - '0';
       ch = getchar();
   }
   return x * f;
}

ll m_pow(ll x, ll n, ll m) {
   ll res = 1;
   while (n > 0) {
       if (n & 1)
           res = (res * x) % m;
       x = (x * x) % m;
       n >>= 1;
   }
   return res % m;
}

struct node {
   int minn, maxn;

   bool operator<(const node &rhs) const {
       return minn < rhs.minn;
   }
} a[N];

vector<int> v[N];
bool hashv[N] = {0};
int n, m, cnt = 0;

inline void dfs(int k) {
   hashv[k] = 1;
   a[cnt] = node{min(a[cnt].minn, k), max(a[cnt].maxn, k)};
   for (auto x:v[k])
       if (!hashv[x])
           dfs(x);
}

int main() {
   io_opt;
   int x, y;
   cin >> n >> m;
   rep(i, 1, m) {
       cin >> x >> y;
       v[x].push_back(y);
       v[y].push_back(x);
   }
   for (int i = 1; i <= n; i++)
       if (!hashv[i]) {
           ++cnt;
           a[cnt] = node{i, i};
           dfs(i);
       }
   sort(a + 1, a + cnt + 1);
   int mx = a[1].maxn,ans = 0;
   for(int i=2;i<=cnt;i++){
       if(a[i].minn < mx)
           ans++;
       mx=max(mx,a[i].maxn);
   }
   cout << ans << endl;
   return 0;
}

E 区间dp

nn个点(n80n\leq 80),每个点可以覆盖到[xisi,xi+si][x_i-s_i,x_i+s_i]的区间,每次花费1个单位的代价可以使任一个点覆盖区间变为[xisi1,xi+si+1][x_i-s_i-1,x_i+s_i+1],求覆盖[1,m][1,m]的最小代价。

dpidp_i为覆盖[i,m][i,m]的最小代价,初始化dpi=midp_i = m-i,那么对于每一个点灯塔,如果i+1可以被覆盖到,dpi=dpi+1dp_i=dp_{i+1},否则对于lj>iu=lji1dpi=min(dpi,u+dpmin(m,u+rj))l_j>i的灯塔,u=l_j-i-1,dp_i=min(dp_i,u+dp_{min(m, u+r_j)})

posted @ 2019-11-21 17:29  Mr.doublerun  阅读(19)  评论(0)    收藏  举报