Codeforces Round #561题解

A题

分奇偶讨论

B题

猜结论找规律题

C题

首先可以发现一个性质,这也是绝对值的性质,数的正负不影响答案

因此我们全部转化成正数,对于求取无序对,我们枚举每一个数的时候,只要在他两倍内的其他数都可以,因此这个二分求解

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
vector<int> num;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int n;
    int i;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>a[i];
        a[i]=abs(a[i]);
    }
    sort(a+1,a+1+n);
    ll ans=0;
    for(i=1;i<n;i++){
        int l=i+1,r=n;
        while(l<r){
            int mid=l+r+1>>1;
            if(a[mid]<=2*a[i]){
                l=mid;
            }
            else{
                r=mid-1;
            }
        }
        if(a[l]<=2*a[i]){
            ans+=l-i;
        }
    }
    cout<<ans<<endl;
    return 0;
}
View Code

D题

推式子的好题,首先根据上下界限定大小,如果可以在50个以内

那么一定有解,其次我们根据题目的性质推出有关b的等式

这样我们就可以贪心从第一位开始考虑,每次都取限制内最大的,这样最后一个就一定能满足条件

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int main(){
    ios::sync_with_stdio(false);
    int q;
    cin>>q;
    while(q--){
        ll a,b,m;
        cin>>a>>b>>m;
        if(a==b){
            cout<<1<<" "<<a<<endl;
            continue;
        }
        int n=0;
        while(n<=49){
            n++;
            ll l=(1ll<<(n-1))*(a+1);
            ll r=(1ll<<(n-1))*(a+m);
            if(l>b){
                n=51;
                break;
            }
            if(b>=l&&b<=r){
                break;
            }
        }
        if(n>=50){
            cout<<-1<<endl;
            continue;
        }
        ll sum=a;
        ll tot=0;
        cout<<n+1<<" "<<a<<" ";
        for(int i=1;i<n;i++){
            ll d=b-(1ll<<(n-1))*a-(1ll<<n-1);
            ll tmp=min(m-1,(d-tot)/(1ll<<(n-i-1)));
            tot+=tmp*(1ll<<(n-i-1));
            cout<<sum+tmp+1<<" ";
            sum+=sum;
            sum+=tmp+1;
        }
        cout<<b<<endl;
    }
    return 0;
}
View Code

E题

数学思维结论题,如果任意两个集合有交点,那么有解,否则无解

因为如果有两个集合没有交点,假设lcma>补集,那么因为集合b是补集的子集,因此lcma>lcmb,这样不合法

如果都有交点,那么初始化数是1,对于每个集合数都把他乘上一个不一样的质数,这样任意一个集合的lcm都是这是质数的积,但是不包含这个集合的补集,他的lcm因为没有这个质数,所以一定小

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
bitset<10010> bt[100];
int main(){
    ios::sync_with_stdio(false);
    int m,n;
    cin>>m>>n;
    int i;
    for(i=1;i<=m;i++){
        int k;
        cin>>k;
        for(int j=1;j<=k;j++){
            int x;
            cin>>x;
            bt[i].set(x);
        }
        for(int j=1;j<i;j++){
            if((bt[i]&bt[j]).none()){
                cout<<"impossible"<<endl;
                return 0;
            }
        }
    }
    cout<<"possible"<<endl;
    return 0;
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/14546763.html