【CF】Codeforces Round #538 (Div. 2)

太可怕了,我以为我F题最后提交上去了,结果发现并没有orz orz orz A题 水题模拟
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>

using namespace std;

int x,y,z;
int a,b,c;
int main() {
    scanf("%d%d%d",&x,&y,&z);
    cin>>a>>b>>c;
    if(a>=x&&a+b>=x+y&&a+b+c>=x+y+z) puts("YES");
    else puts("NO");
}
B题 大胆猜测只用取前m*k个数,打上标记分每k个分块就可以了
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#define int long long
using namespace std;
const int maxn = 4e5+5;
int n,m,k;
struct node{
    int wz,zhi;
}z[maxn],now[maxn];
int tot;
bool cmp(node aa,node bb) {
    return aa.zhi > bb.zhi;
}
bool ccp(node aa,node bb) {
    return aa.wz < bb.wz;
}
main() {
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++) cin>>z[i].zhi,z[i].wz = i;
    sort(z+1,z+1+n,cmp);
    int ans = 0;
    for(int i=1;i<=m*k;i++) {
        now[i] = z[i];
        ans+=now[i].zhi;
    }
    sort(now+1,now+1+m*k,ccp);
    cout<<ans<<endl;
    for(int i=1;i<k;i++) {
        printf("%I64d ",now[i*m].wz);
    }
}
C题 求n!在b进制下末尾有多少个0 类似找10进制下一样的方法,如果b可以表示为p1^k1 * p2^k2 * p3^k3 那么为对于n!包含因数pi^ki最少的个数。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#define int long long
using namespace std;
int n,b;
int mi;
int CNT;
int zz; 
void facgetnum(int o,int x) {
    if(o<x) return;
    CNT+=o/x;
    if(CNT/zz>=mi) return;
    facgetnum(o/x,x);
}

main() {
    mi = 1e18;
    cin>>n>>b;
    for(int i=2;i*i<=b;i++) {
        if(b%i==0) {
            int o = 0;
            while(b%i==0) o++,b/=i;
            CNT = 0; 
            zz = o;
            facgetnum(n,i);
            mi = min(mi,CNT/o);
        }
    }
    if(b>1) {
        CNT = 0;
        zz = 1;
        facgetnum(n,b);
        mi = min(mi,CNT);       
    }
    cout<<mi;
}
D 选择一个初始点,同色的为一个块,每一次可以将包含起始点块的左或右的那个方块变色,问最少操作次数 将同色unique之后就是一个区间配对的问题了(区间同颜色配对之后可以节省一次,否则直接变就是颜色-1次)
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>

using namespace std;
int f[5005][5005];
int n;
int a[5005],b[5005],tot;
int main() {
    cin>>n;
    for(int i=1;i<=n;i++) {
        cin>>a[i];
        if(a[i]!=a[i-1]) b[++tot] = a[i];
    }
    for(int cd=2;cd<=tot;cd++) {
        for(int l=1;l+cd-1<=tot;l++) {
            int r = l+cd-1;
            f[l][r] = max(f[l+1][r],f[l][r-1]);
            if(b[l]==b[r]) f[l][r] = max(f[l][r],f[l+1][r-1]+1);
        }
    }
    cout<<tot-f[1][tot]-1;
}
E 补 给出一个等差数列将其乱序,你有2种询问操作: 1.“? i",询问ai的值 2."> x",询问序列中是否有元素大于x 要在60次询问内询问出该序列的首项和公差 我们显然可以用30次(log n)找出序列最大值。对于序列公差,然后我们可以rand多次,找出30个数(以及最大值)。这样之后两两作差之后的最大公约数就是公差。这样就可以找到 首项最大值-(n-1)*d 和公差 d 了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<cstdlib>
using namespace std;

int n;
void fl() {
    fflush(stdout);
}
int a[50];
int gcd(int a,int b) {
    return !b?a:gcd(b,a%b); 
}
int grd() {
    return (rand()<<15)|rand();
}
int main() {
    scanf("%d",&n);
    srand(time(NULL)^n);
    int o = 0;
    for(int i=29;i>=0;i--) {
        cout<<"> "<<min((int)1e9,o+(1<<i))<<endl; 
        fl();
        int x; cin>>x;
        if(x==1) o=min(o+(1<<i),(int)1e9); 
    }
    o++;
    for(int i=1;i<=30;i++) {
        cout<<"? "<<grd()%n+1<<endl;
        fl();
        cin>>a[i];
    }
    sort(a+1,a+1+30);
    int cnt = unique(a+1,a+1+30)-a-1;
    int oyo = a[2]-a[1];
    a[cnt+1] = o;
    for(int i=2;i<cnt+1;i++) oyo = gcd(oyo,a[i+1]-a[i]);
    cout<<"! "<<o-oyo*(n-1)<<' '<<oyo<<endl;
}
F 一个序列,区间乘c,或求区间[l,r],$ \varphi(\prod \limits_{i=l}^{r} a_i) $,c和区间初始值<=300. 可以想到,询问主要就是问区间的乘积和区间乘因数包含哪些质数,线段树裸题维护bitset(哪些质数)和区间乘就可以了。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
const int maxn = 4e5+5;
const int mod = 1e9+7;
int add(int x,int y){ x+=y; return x>=mod?x-mod:x; }
int sub(int x,int y){ x-=y; return x<0?x+mod:x; }
int mul(int x,int y){ return 1ll*x*y%mod; }
int ksm(int a,int b) {
    int ans = 1;
    for(;b;b>>=1,a=mul(a,a))
        if(b&1) ans = mul(ans,a);
    return ans;
}
int n,q;
int cnt,pri[305],dy[305],lat[305]; bool mk[305];
void init() {
    mk[0] = mk[1] = 1;
    for(int i=2;i<=300;i++) {
        if(!mk[i]) { pri[++cnt] = i; lat[i]=cnt; dy[cnt] = mul(ksm(i,mod-2),i-1); }
        for(int j=1;j<=cnt&&1ll*pri[j]*i<=300;j++) {
            int k = pri[j]*i;
            mk[k] = 1;
            lat[k] = j;
            if(i%pri[j]==0) break;
        }
    }
}
struct node{
    node *ls,*rs;
    bitset<64>b,lab;
    int mt,laz;
}z[maxn*2],*rt; int tot;
void upd(node *&p) {
    p->b = p->ls->b|p->rs->b;
    p->mt = mul(p->ls->mt,p->rs->mt);
}
void ptd(node *&p,int l,int mid,int r) {
    p->ls->laz = mul(p->ls->laz,p->laz);
    p->rs->laz = mul(p->rs->laz,p->laz); 
    p->ls->mt = mul(p->ls->mt,ksm(p->laz,mid-l+1));
    p->rs->mt = mul(p->rs->mt,ksm(p->laz,r-mid));
    p->ls->b |= p->lab; p->rs->b |= p->lab; 
    p->ls->lab |= p->lab; p->rs->lab |= p->lab;
    p->laz = 1;
}
void maketree(node *&p,int l,int r) {
    p = &z[++tot];
    p->laz = 1;
    if(l==r) {
        int x; scanf("%d",&x);
        p->mt = x;
        while(x!=1) {
            p->b[lat[x]] = 1;
            x/=pri[lat[x]];
        }
        return;
    }
    int mid = (l+r)>>1;
    maketree(p->ls,l,mid); maketree(p->rs,mid+1,r);
    upd(p);
}
void upd(node *&p,int l,int r,int x,int y,int d) {
    if(x<=l&&r<=y) {
        p->mt = mul(p->mt,ksm(d,r-l+1));
        p->laz = mul(p->laz,d);
        while(d!=1) {
            p->b[lat[d]] = 1;
            p->lab[lat[d]] = 1;
            d/=pri[lat[d]];
        }
        return;
    }
    int mid = (l+r)>>1;
    ptd(p,l,mid,r);
    if(y<=mid) upd(p->ls,l,mid,x,y,d);
    else if(x>mid) upd(p->rs,mid+1,r,x,y,d);
    else upd(p->ls,l,mid,x,y,d),upd(p->rs,mid+1,r,x,y,d);
    upd(p);
}
bitset<64>bbb;
int query(node *&p,int l,int r,int x,int y) {
    if(x<=l&&r<=y) {
        bbb|=p->b;
        return p->mt;
    }
    int mid = (l+r)>>1;
    ptd(p,l,mid,r);
    if(y<=mid) return query(p->ls,l,mid,x,y);
    else if(x>mid) return query(p->rs,mid+1,r,x,y);
    else return mul(query(p->ls,l,mid,x,y),query(p->rs,mid+1,r,x,y));
}
char ss[15];
int main() {
    init();
    scanf("%d%d",&n,&q);
    maketree(rt,1,n);
    int l,r,x;
    for(int i=1;i<=q;i++) {
        scanf("%s",&ss[1]);
        if(ss[1]=='M') {
            scanf("%d%d%d",&l,&r,&x);
            upd(rt,1,n,l,r,x);
        } else {
            scanf("%d%d",&l,&r);
            bbb.reset();
            int ans = query(rt,1,n,l,r);
            for(int i=1;i<=cnt;i++) {
                if(bbb[i]) ans = mul(ans,dy[i]);
            }
            printf("%d\n",ans);
        }
    }
}
posted @ 2019-02-23 16:58  Newuser233  阅读(7)  评论(0)    收藏  举报