2018-2019 ACM-ICPC, NEERC, Southern Subregional Contest, Qualification Stage(11/12)

2018-2019 ACM-ICPC, NEERC, Southern Subregional Contest, Qualification Stage

A. Coffee Break
排序之后优先队列搞一下就好了

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e5+7;
const int INF = 0x3f3f3f3f;
int n,m,d,pos[MAXN];

int main(){
    ____();
    cin >> n >> m >> d;
    vector<pair<int,int>> vec(n);
    for(int i = 0; i < n; i++){
        cin >> vec[i].first;
        vec[i].second = i;
    }
    sort(vec.begin(),vec.end());
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> que;
    int tot = 0;
    que.push(make_pair(-INF,++tot));
    for(auto &p : vec){
        int id = p.second, w = p.first;
        if(que.top().first+d>=w) que.push(make_pair(-INF,++tot));
        auto pr = que.top();
        que.pop();
        pr.first = w;
        pos[id] = pr.second;
        que.push(pr);
    }
    cout << tot << endl;
    for(int i = 0; i < n; i++) cout << pos[i] << ' '; cout << endl;
    return 0;
}

B.Glider
如果到了一块区间,那么必然会走完这块区间
而且必然是从某一块区间的最左边开始的
所以枚举每一个区间,二分找到最右边的可以到达的区间,用前缀和维护一下

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e5+7;
int n,h,pref[MAXN];
pair<int,int> pr[MAXN];
void solve(){
    cin >> n >> h;
    for(int i = 1; i <= n; i++) cin >> pr[i].first >> pr[i].second;
    for(int i = 2; i <= n; i++) pref[i] = pref[i-1] + pr[i].first - pr[i-1].second;
    int ret = 0;
    for(int i = 1; i <= n; i++){
        int l = i, r = n;
        while(l<=r){
            int mid = (l+r) >> 1;
            if(pref[mid] - pref[i] < h) l = mid + 1;
            else r = mid - 1;
        }
        ret = max(ret,pr[r].second - pr[i].first + 1 + h - (pref[r] - pref[i]) - 1);
    }
    cout << ret << endl;
}
int main(){
    ____();
    solve();
    return 0;
}

C.Bacteria
除gcd之后判断是否是\(2\)的次方
然后全部加和不断加\(lowbit\)直到变成\(2^x\)即可

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e5+7;
typedef long long int LL;
#define lowbit(x) (x&-x)
LL n,A[MAXN];
int main(){
    ____();
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> A[i];
    LL g = 0; for(int i = 1; i <= n; i++) g = __gcd(g,A[i]);
    for(int i = 1; i <= n; i++) A[i] /= g;
    for(int i = 1; i <= n; i++) if(__builtin_popcount(A[i])!=1){
        cout << -1 << endl;
        return 0;
    }
    LL tot = accumulate(A+1,A+1+n,0ll);
    int ret = 0;
    while(tot!=lowbit(tot)) tot += lowbit(tot), ret++;
    cout << ret << endl;
    return 0;
}

D.Masquerade strikes back
对于每个数找出所有因子,然后组合一下

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e5+7;
int n;
pair<int,int> A[MAXN],ret[MAXN];
vector<int> prime;
bool npm[MAXN];
void sieve(){
    for(int i = 2; i < MAXN; i++){
        if(!npm[i]) prime.push_back(i);
        for(int j = 0; j < (int)prime.size(); i++){
            if(i*prime[j]>=MAXN) break;
            npm[i*prime[j]] = true;
            if(i%prime[j]==0) break;
        }
    }
}
vector<pair<int,int> > getfact(int x){
    map<int,int> fct;
    for(int i = 0; prime[i] * prime[i] <= x; i++){
        int &p = prime[i];
        while(x%p==0){
            fct[p]++;
            x /= p;
        }
        if(x==1) break;
    }
    if(x!=1) fct[x]++;
    vector<pair<int,int> > vec;
    for(auto &p : fct) vec.push_back(p);
    return vec;
}
void dfs(int pos, vector<pair<int,int> > &vec, vector<int> &vc, int &cnt, int prod){
    if(pos==(int)vec.size()){
        vc.push_back(prod);
        cnt--; return;
    }
    for(int i = 0; i <= vec[pos].second; i++){
        if(i) prod *= vec[pos].first;
        dfs(pos+1,vec,vc,cnt,prod);
        if(!cnt) return;
    }
}
int main(){
    ____();
    sieve();
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> A[i].first;
    for(int i = 1; i <= n; i++) A[i].second = i;
    sort(A+1,A+1+n);
    for(int i = 1, r; i <= n; i = r + 1){
        r = i;
        while(r<n and A[r+1].first==A[i].first) r++;
        int num = r - i + 1;
        if(A[i].first==1){
            if(num>1){
                cout << "NO" << endl;
                return 0;
            }
            else{
                ret[A[i].second] = make_pair(1,1);
                continue;
            }
        }
        vector<pair<int,int> > vec = getfact(A[i].first);
        int tot = 1;
        for(auto &pr : vec) tot = tot * (pr.second + 1);
        if(tot<num){
            cout << "NO" << endl;
            return 0;
        }
        vector<int> vc;
        dfs(0,vec,vc,num,1);
        for(int j = i; j <= r; j++) ret[A[j].second] = make_pair(vc[j-i],A[i].first/vc[j-i]);
    }
    cout << "YES" << endl;
    for(int i = 1; i <= n; i++) cout <<ret[i].first << ' ' << ret[i].second << endl;
    return 0;
}

E.Painting the Fence
线段树区间置值
重复出现的修改只需要改一次

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 3e5+7;
int n,m,A[MAXN],vis[MAXN];
vector<int> pos[MAXN];
struct SegmentTree{
    int l[MAXN<<2],r[MAXN<<2],col[MAXN<<2];
    #define ls(rt) rt << 1
    #define rs(rt) rt << 1 | 1
    void build(int L, int R, int rt = 1){
        l[rt] = L, r[rt] = R;
        if(L+1==R){
            col[rt] = A[L];
            return;
        }
        int mid = (L+R) >> 1;
        build(L,mid,ls(rt)); build(mid,R,rs(rt));
    }
    void pushdown(int rt){
        if(!col[rt]) return;
        col[ls(rt)] = col[rs(rt)] = col[rt];
        col[rt] = 0;
    }
    void update(int L, int R, int c, int rt = 1){
        if(L>=r[rt] or l[rt]>=R) return;
        if(L<=l[rt] and r[rt]<=R){
            col[rt] = c;
            return;
        }
        pushdown(rt);
        update(L,R,c,ls(rt)); update(L,R,c,rs(rt));
    }
    int query(int pos, int rt = 1){
        if(l[rt] + 1 == r[rt]) return col[rt];
        pushdown(rt);
        int mid = (l[rt] + r[rt]) >> 1;
        if(pos<mid) return query(pos,ls(rt));
        else return query(pos,rs(rt));
    }
}ST;
int main(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        scanf("%d",&A[i]);
        pos[A[i]].push_back(i);
    }
    scanf("%d",&m);
    ST.build(1,MAXN);
    for(int i = 1; i <= m; i++){
        int op; scanf("%d",&op);
        if(vis[op]) continue;
        vis[op] = true;
        int lmax = 0x3f3f3f3f, rmax = 0;
        for(auto p : pos[op]) if(ST.query(p)==op) lmax = min(lmax,p), rmax = max(rmax,p);
        if(lmax>=rmax) continue;
        ST.update(lmax,rmax+1,op);
    }
    for(int i = 1; i <= n; i++) printf("%d ",ST.query(i));
    puts("");
    return 0;
}

F.Tickets
前缀和

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e6+7;
const int D = 30;
int n,pre[MAXN][D];

int calc(int x){
    int l = x / 1000;
    int r = x % 1000;
    int ret = 0;
    while(l) ret += l % 10, l /= 10;
    while(r) ret -= r % 10, r /= 10;
    return abs(ret);
}
void preprocess(){
    pre[0][0] = 1;
    for(int i = 1; i < 1000000; i++){
        int x = calc(i);
        for(int j = 0; j < D; j++) pre[i][j] = pre[i-1][j];
        pre[i][x]++;
    }
}
void solve(){
    int x; cin >> x;
    int ret = 0, v = calc(x);
    for(int i = 0; i < v; i++) ret += pre[x][i];
    cout << ret << endl;
}
int main(){
    ____();
    preprocess();
    for(cin >> n; n; n--) solve();    
    return 0;
}

G.Tree Reconstruction
拉成一条链即可

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1111;
set<int> S;
int n;
pair<pair<int,int>,int> pr[MAXN];
pair<int,int> ret[MAXN];
int main(){
    ____();
    cin >> n;
    for(int i = 1; i < n; i++) cin >> pr[i].first.first >> pr[i].first.second;
    for(int i = 1; i < n; i++) if(pr[i].first.first>pr[i].first.second) swap(pr[i].first.first,pr[i].first.second);
    for(int i = 1; i < n; i++){
        if(pr[i].first.second!=n){
            cout << "NO" << endl;
            return 0;
        }
        pr[i].second = i;
    }
    sort(pr+1,pr+n);
    for(int i = 1; i <= n; i++) S.insert(i);
    int maxx = 0;
    vector<int> vec;
    for(int i = 1; i < n; i++){
        if(pr[i].first.first>maxx){
            vec.push_back(pr[i].first.first);
            S.erase(pr[i].first.first);
            maxx = pr[i].first.first;
        }
        else{
            int u = *S.begin();
            S.erase(S.begin());
            if(u>pr[i].first.first){
                cout << "NO" << endl;
                return 0;
            }
            vec.push_back(u);
        }
    }
    vec.push_back(n);
    cout << "YES" << endl;
    for(int i = 1; i < n; i++) ret[pr[i].second] = make_pair(vec[i-1],vec[i]);
    for(int i = 1; i < n; i++) cout << ret[i].first << ' ' << ret[i].second << endl;
    return 0;
}

H.Theater Square
简单计算一下

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
int n,m,x1,y1,x2,y2;
int main(){
    ____();
    cin >> n >> m >> x1 >> y1 >> x2 >> y2;
    cout << ((x1 - 1 + n - x2) * (m%2) + (x2-x1+1) * ((y1-1)%2 + (m-y2)%2) + 1) / 2 << endl;
    return 0;
}

I.Heist
签到

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
int n,A[1111];
int main(){
    ____();
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> A[i];
    cout << *max_element(A+1,A+1+n) - *min_element(A+1,A+1+n) + 1 - n << endl;
    return 0;
}

J.Buying a TV Set
除gcd之后取长宽最小倍数

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef long long int LL;
LL a,b,x,y;
int main(){
    ____();
    cin >> a >> b >> x >> y;
    LL d = __gcd(x,y);
    x /= d; y /= d;
    cout << min(a/x,b/y) << endl;
    return 0;
}

K.Medians and Partition
大于等于\(m\)的变成\(1\)
小于\(m\)的变成\(-1\)
然后贪心分段,保证分段之后前后依然是\(m\ good\)

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 5e3+7;
int n,m,A[MAXN],pref[MAXN];
int main(){
    ____();
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> A[i];
    for(int i = 1; i <= n; i++){
        if(A[i]>=m) A[i] = 1;
        else A[i] = -1;
    }
    for(int i = 1; i <= n; i++) pref[i] = pref[i-1] + A[i];
    if(pref[n]<=0){
        cout << 0 << endl;
        return 0;
    }
    int last = 0, num = 1;
    for(int i = 1; i <= n; i++){
        if(pref[i]-pref[last]>0 and pref[n] - pref[i]>0){
            num++;
            last = i;
        }
    }
    cout << num << endl;
    return 0;
}

L.Ray in the tube
🔗

posted @ 2020-05-23 22:15  _kiko  阅读(764)  评论(0编辑  收藏  举报