Amphetamine的cf日记

Posted on 2018-02-15 14:55  Amphetamine  阅读(166)  评论(0编辑  收藏  举报

之前挂上的

今天填坑

 

2018.2.14 #462

A

给两个集合,B分别可以从一个集合中选一个数,B想乘积最大,A想最小,A可以删除一个第一个集合中的元素,问最小能达到多少。

这题。。水死啦。我居然还wa了一发,因为ans初值定的0.。。。。我真是傻。

n3暴力就行

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000000000000001ll
int n,m;
ll a[100],b[100];
ll ans=inf;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=m;i++)cin>>b[i];
    for(int k=1;k<=n;k++){
    ll ret=-inf;
    for(int i=1;i<=n;i++){
        if(i==k)continue;
        for(int j=1;j<=m;j++){
            ret=max(ret,a[i]*b[j]);
        }
    }
    ans=min(ans,ret);
    }    
    cout<<ans<<endl;
    return 0;
} 
View Code

 

B

我记得小时候的脑筋急转弯

6666=4

8888=8

1234=1

5678=?

哈哈

数圈嘛

先全输出8,剩一个就输出6,剩下的输出1

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int k;

int main(){
    cin>>k;
    if(k>36){
        cout<<-1<<endl;
        return 0;
    }
    else {
        for(int i=1;i<=18;i++){
            if(k>=2){
                cout<<8;
                k-=2;
            }
            else if(k==1){
            cout<<6;k--;}
            else cout<<1;
        }
    }
    return 0;
} 
View Code

 

C

一个只有1,2的序列,你可以翻转一次任意子串,问翻转之后最长不下降子序列。

选择很多???

这题随便做嘛。

我是利用了一个小性质,就是从1到2的分界点,一定是在翻转的区间里,否则没意义。

然后枚举翻转区间,维护一下最长不下降子序列就好了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[2010];
int l1[2010],l2[2010],r1[2010],r2[2010];
int n;
int ans;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        l1[i]=l1[i-1];
        l2[i]=l2[i-1];
        if(a[i]==1)l1[i]++;
        else l2[i]++;
    }
    for(int i=n;i>=1;i--){
        r1[i]=r1[i+1];
        r2[i]=r2[i+1];
        if(a[i]==1)r1[i]++;
        else r2[i]++;
    }
    for(int i=1;i<=n+1;i++){
        ans=max(ans,l1[i-1]+r2[i]);
        int ret=l1[i-1]+r2[i];
        int j=i-1;
        while(j&&a[j]==1)j--;
        int tt=0;
        for(;j>0;j--){
            if(a[j]==2)tt++;
            else if(tt)tt--;
            ans=max(ans,ret+tt);
        }
    }
    cout<<ans<<endl;
    return 0;
} 
View Code

 

D

好题!!!

 

n order to put away old things and welcome a fresh new year, a thorough cleaning of the house is a must.

Little Tommy finds an old polynomial and cleaned it up by taking it modulo another. But now he regrets doing this...

Given two integers p and k, find a polynomial f(x) with non-negative integer coefficients strictly less than k, whose remainder is p when divided by (x + k). That is, f(x) = q(x)·(x + k) + p, where q(x) is a polynomial (not necessarily with integer coefficients).

Input

The only line of input contains two space-separated integers p and k (1 ≤ p ≤ 1018, 2 ≤ k ≤ 2 000).

Output

If the polynomial does not exist, print a single integer -1, or output two lines otherwise.

In the first line print a non-negative integer d — the number of coefficients in the polynomial.

In the second line print d space-separated integers a0, a1, ..., ad - 1, describing a polynomial  fulfilling the given requirements. Your output should satisfy 0 ≤ ai < k for all 0 ≤ i ≤ d - 1, and ad - 1 ≠ 0.

If there are many possible solutions, print any of them.

 

这题没有special judge

只有唯一解

根据多项式意义,可以发现,f(x)的第一位是可以立即确定的,然后根据第一位可以推出第二位....依次类推。

然后我们发现,这个不断从上一项推出下一项的过程,很像之前做过的负进制转换。(luoguP 1107)

吐槽一下,我当时发现很像,并且过了pretest之后,告诉洛谷群,结果群里面一堆小孩说我钓鱼。。。。。

这件事情教育我们,干什么要先过脑子,,,,,

其实就是把p转化为(-k)进制,输出,结束。

(自行去luogu题解粘代码)

E

计算几何,,,,,gg

#include<bits/stdc++.h>
using namespace std;
struct point{
    double x,y;
};  
double xmult(point p1,point p2,point p0){  
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);  
}  
double dist(point p1,point p2){  
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));  
}  

point intersection(point u1,point u2,point v1,point v2){  
    point ret=u1;  
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))  
            /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));  
    ret.x+=(u2.x-u1.x)*t;  
    ret.y+=(u2.y-u1.y)*t;  
    return ret;  
}  
const double eps=1e-8;
point dot_to_circle(point c,double r,point p){  
    point u,v;  
    if (dist(p,c)<eps)  
        return p;  
    u.x=c.x+r*fabs(c.x-p.x)/dist(c,p);  
    u.y=c.y+r*fabs(c.y-p.y)/dist(c,p)*((c.x-p.x)*(c.y-p.y)<0?-1:1);  
    v.x=c.x-r*fabs(c.x-p.x)/dist(c,p);  
    v.y=c.y-r*fabs(c.y-p.y)/dist(c,p)*((c.x-p.x)*(c.y-p.y)<0?-1:1);  
    return dist(u,p)<dist(v,p)?u:v;  
}  
void intersection_line_circle(point c,double r,point l1,point l2,point& p1,point& p2){  
    point p=c;  
    double t;  
    p.x+=l1.y-l2.y;  
    p.y+=l2.x-l1.x;  
    p=intersection(p,c,l1,l2);  
    t=sqrt(r*r-dist(p,c)*dist(p,c))/dist(l1,l2);  
    p1.x=p.x+(l2.x-l1.x)*t;  
    p1.y=p.y+(l2.y-l1.y)*t;  
    p2.x=p.x-(l2.x-l1.x)*t;  
    p2.y=p.y-(l2.y-l1.y)*t;  
}  
void intersection_circle_circle(point c1,double r1,point c2,double r2,point& p1,point& p2){  
    point u,v;  
    double t;  
    t=(1+(r1*r1-r2*r2)/dist(c1,c2)/dist(c1,c2))/2;  
    u.x=c1.x+(c2.x-c1.x)*t;  
    u.y=c1.y+(c2.y-c1.y)*t;  
    v.x=u.x+c1.y-c2.y;  
    v.y=u.y-c1.x+c2.x;  
    intersection_line_circle(c1,r1,u,v,p1,p2);  
}  

int n;
int sqr(int x){
    return x*x;
}
int cross(int a,int b,int c,int d,int e,int f){
    if(sqr(a-d)+sqr(b-e)>=sqr(c+f))return 0;
    if(sqr(a-d)+sqr(b-e)<=sqr(c-f))return 0;
    return 1;
}
int a,b,c,d,e,f,g,h,i;
int ct(int a,int b,int c,int d,int e,int f){
    if(sqr(a-d)+sqr(b-e)==sqr(c+f))return 1;
    if(sqr(a-d)+sqr(b-e)==sqr(c-f))return 2;
    return 0;
}
//3
//-4 4 4
//2 4 2
//-1 0 6



int main()
{
    cin>>n;
    if(n==1){
        cin>>a>>b>>c;
        cout<<2;
        return 0;
    }
    if(n==2){
        cin>>a>>b>>c>>d>>e>>f;
        cout<<3+cross(a,b,c,d,e,f);
        return 0;
    }
    cin>>a>>b>>c>>d>>e>>f>>g>>h>>i;
    int ret=4;
    if(cross(a,b,c,d,e,f)&&cross(d,e,f,g,h,i)&&cross(g,h,i,a,b,c)){
    ret=8;
    double num1,num2,num3,num4,num5,num6;
    double r1,r2,r3;
    num1=a,num2=b,r1=c;
    num3=d,num4=e,r2=f;
    num5=g,num6=h,r3=i;
    point w,ww,p1,p2;
    w.x=a,w.y=b;ww.x=d,ww.y=e;
    intersection_circle_circle(w,r1,ww,r2,p1,p2);
    num1=p1.x,num2=p1.y,num3=p2.x,num4=p2.y;
    if(fabs((num1-num5)*(num1-num5)+(num2-num6)*(num2-num6)-r3*r3)<eps)ret--;
    if(fabs((num3-num5)*(num3-num5)+(num4-num6)*(num4-num6)-r3*r3)<eps)ret--;
    cout<<ret<<endl;
    }
    else {
        ret=4+cross(a,b,c,d,e,f)+cross(d,e,f,g,h,i)+cross(g,h,i,a,b,c);
        if(ret==6){
            if((ct(a,b,c,d,e,f)+1)/2+(ct(d,e,f,g,h,i)+1)/2+(ct(g,h,i,a,b,c)+1)/2){
                double num1,num2,num3,num4,num5,num6;
    double r1,r2,r3;
    num1=a,num2=b,r1=c;
    num3=d,num4=e,r2=f;
    
    
                if(cross(a,b,c,d,e,f)){
                    point w,ww,p1,p2;
                    w.x=a,w.y=b;ww.x=d,ww.y=e;
                    intersection_circle_circle(w,r1,ww,r2,p1,p2);
                    num1=p1.x,num2=p1.y,num3=p2.x,num4=p2.y;
                    num5=g,num6=h,r3=i;if(fabs((num1-num5)*(num1-num5)+(num2-num6)*(num2-num6)-r3*r3)>eps&&fabs((num3-num5)*(num3-num5)+(num4-num6)*(num4-num6)-r3*r3)>eps)ret++;
                }
                else if(cross(a,b,c,g,h,i)){point w,ww,p1,p2;
                    w.x=a,w.y=b;ww.x=g,ww.y=h;
                    intersection_circle_circle(w,r1,ww,i,p1,p2);
                    num1=p1.x,num2=p1.y,num3=p2.x,num4=p2.y;
                    num5=d,num6=e,r3=f;if(fabs((num1-num5)*(num1-num5)+(num2-num6)*(num2-num6)-r3*r3)>eps&&fabs((num3-num5)*(num3-num5)+(num4-num6)*(num4-num6)-r3*r3)>eps)ret++;
                }
            }
        }
        else if(ret==5){
            ret+=((ct(a,b,c,d,e,f)+1)/2+(ct(d,e,f,g,h,i)+1)/2+(ct(g,h,i,a,b,c)+1)/2)/2;
        }
        if(ret==4){
            if(ct(a,b,c,d,e,f)&&ct(d,e,f,g,h,i)&&ct(g,h,i,a,b,c)){
                double num1,num2,num3,num4;
                if(ct(a,b,c,d,e,f)==1)num1=a+1.0*(d-a)*c/(c+f),num2=b+1.0*(e-b)*c/(c+f);
                else {
                    if(c>f){
                        num1=a+1.0*(d-a)*c/(c-f),num2=b+1.0*(e-b)*c/(c-f);
                    }
                    else {
                        num1=d+1.0*(a-d)*f/(f-c),num2=e+1.0*(b-e)*f/(f-c);
                    }
                }
                if(ct(g,h,i,a,b,c)==1)num3=a+1.0*(g-a)*c/(c+i),num4=b+1.0*(h-b)*c/(c+i);
                else {
                    if(c>i){
                        num3=a+1.0*(g-a)*c/(c-i),num4=b+1.0*(h-b)*c/(c-i);
                    }
                    else {
                        num3=d+1.0*(a-g)*i/(i-c),num4=e+1.0*(b-h)*i/(i-c);
                    }
                }
                if(fabs(num3-num1)>eps||fabs(num4-num2)>eps)ret++;
            }
        }
        cout<<ret<<endl;
    }
    return 0;
}
View Code

 

为什么老是说我颓废呢,,,,,我不颓废啊。

 

感觉,带修改莫队真是简单。

codeforces round#466

因为F一直不会,当时想到莫队,怎奈不会修改。

其实很简单,中午用了3分钟就看明白待修改莫队了。

然后F题就变成了大水题。。。

这场比赛应该AK的,,,,而我却没把握住机会。

多少有点遗憾吧。

给一个大小为n的集合,和一个常数d,问最少删除多少个数才能使得集合中,最大值与最小值相差小于k。

(不懂Doggu辣么强的选手为什么没有秒切并1A)

cf的div2T1从来不用什么算法。。。

sort之后枚举最大最小值即可。

#include<bits/stdc++.h>
using namespace std;
int a[110];
int n,d;
int ans=10000;
int main(){
    cin>>n>>d;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        int ret=i-1;
        for(int j=n;j>i;j--){
            if(a[j]-a[i]<=d)break;
            ret++;
        }
        ans=min(ans,ret);
    }
    cout<<ans;
    return 0;
} 
View Code

B

给4个整数,n,k,A,B。

n每次可以-1或/k,代价分别是A,B问用最小代价使n变成1

不说了,直接上代码。都能看懂。

#include<bits/stdc++.h>
using namespace std;

#define ll long long
ll n,k,a,b;
ll ans=0;
int main(){
    cin>>n>>k>>a>>b;
    if(k==1){
        ans=(n-1)*a;
        cout<<ans<<endl;
        return 0;
    }
    while(n!=1){
        if(n%k==0){
            ll tt=(n-n/k)*a;
            ll t=b;
            ans+=min(t,tt);
            n=n/k;
        }
        else {
            if(n>k){
                ans+=(n%k)*a;
                n-=n%k;
            }
            else {
                ans+=(n-1)*a;
                n=1;
            }
        }
    }
    cout<<ans;
    return 0;
} 
View Code

(Doggu这次没打好存粹是心态问题)

C

太水了,不说了,不说了。

前三题绝对是普及组难度的。

D

"We've tried solitary confinement, waterboarding and listening to Just In Beaver, to no avail. We need something extreme."

"Little Alena got an array as a birthday present..."

The array b of length n is obtained from the array a of length n and two integers l and r (l ≤ r) using the following procedure:

b1 = b2 = b3 = b4 = 0.

For all 5 ≤ i ≤ n:

  • bi = 0 if ai, ai - 1, ai - 2, ai - 3, ai - 4 > r and bi - 1 = bi - 2 = bi - 3 = bi - 4 = 1
  • bi = 1 if ai, ai - 1, ai - 2, ai - 3, ai - 4 < l and bi - 1 = bi - 2 = bi - 3 = bi - 4 = 0
  • bi = bi - 1 otherwise

You are given arrays a and b' of the same length. Find two integers l and r (l ≤ r), such that applying the algorithm described above will yield an array b equal to b'.

It's guaranteed that the answer exists.

 

维护四个数,maxl,maxr,minl,minr。不断缩小范围即可。

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define inf 1000000000
int n;
int a[100010];
string b;
int maxl,maxr,minl,minr;
int main(){
    maxl=maxr=inf;
    minl=minr=-inf;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    cin>>b;
    bool f1,f2;
    int L,R;
    for(int i=4;i<n;i++){
        f1=f2=0;
        if(b[i-1]=='0'&&b[i-2]=='0'&&b[i-3]=='0'&&b[i-4]=='0')f1=1;
        if(b[i-1]=='1'&&b[i-2]=='1'&&b[i-3]=='1'&&b[i-4]=='1')f2=1;
        L=min(min(a[i],min(a[i-1],a[i-2])),min(a[i-3],a[i-4])),R=max(max(a[i],max(a[i-1],a[i-2])),max(a[i-3],a[i-4]));
        int x=b[i]-'0';
        int y=b[i-1]-'0';
        if(x==1){
            if(y==1){
                if(f2){
                    minr=max(L,minr);
                }
            }
            else {
                if(f1){
                    minl=max(R+1,minl);
                }
            }
        }
        else {
            if(y==1){
                if(f2){
                    maxr=min(maxr,L-1);
                }
            }
            else {
                if(f1){
                    maxl=min(maxl,R);
                }
            }
        }
    }
    cout<<minl<<" "<<maxr<<endl;
    return 0;
} 
View Code

 

E

 

Since you are the best Wraith King, Nizhniy Magazin «Mir» at the centre of Vinnytsia is offering you a discount.

You are given an array a of length n and an integer c.

The value of some array b of length k is the sum of its elements except for the  smallest. For example, the value of the array [3, 1, 6, 5, 2] with c = 2 is 3 + 6 + 5 = 14.

Among all possible partitions of a into contiguous subarrays output the smallest possible sum of the values of these subarrays.

Input

The first line contains integers n and c (1 ≤ n, c ≤ 100 000).

The second line contains n integers ai (1 ≤ ai ≤ 109) — elements of a.

Output

Output a single integer  — the smallest possible sum of values of these subarrays of some partition of a.

 

很容易得到一个小性质,选长度恰好为c的区间最优。

所以,st表求区间最小值。

dp[i]表示到i位置最大能刨去多大的数

dp[i]=max(dp[i-1],dp[i-10]+qmin(i-10+1,i))

ans=SUM-dp[n];

#include<bits/stdc++.h>
using namespace std;

#define ll long long
int rmq[20][100010];
int lg[100010];
int n,c;
ll dp[100010];
ll sum;
int query(int l,int r){
    int k=lg[r-l+1];
    return min(rmq[k][l],rmq[k][r-(1<<k)+1]);
}
int main(){
    cin>>n>>c;
    for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
    for(int i=1;i<=n;i++){
        cin>>rmq[0][i];
        sum+=rmq[0][i];
    }
    for(int i=1;i<=18;i++){
        for(int j=1;j+(1<<i)-1<=n;j++){
            rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<i-1)]);
        }
    }
    for(int i=c;i<=n;i++){
        dp[i]=max(dp[i-1],dp[i-c]+query(i-c+1,i));
    }
    cout<<sum-dp[n];
    return 0;
} 
View Code

 

F

带修改莫队裸题。

小结论,ans不超过2*sqrt(n)

#include<bits/stdc++.h>
using namespace std;
#define N 400010
map<int,int> ma;
inline int read(){
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x;
}
int dd;
struct Q{
    int l,r,t,id;
}q[N];

struct C{
    int pos,x,o;
}c[N];

int block;
bool comp(Q u,Q v){
    return u.l/block<v.l/block || u.l/block==v.l/block && u.r/block<v.r/block || u.l/block==v.l/block && u.r/block==v.r/block && u.t<v.t;
}

int a[N];
int b[N];
int n,m;
int d[N];
int e[N];
void add(int x,int y){
    b[e[x]]--;
    e[x]+=y;
    b[e[x]]++;
}
int ans[N];
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        if(ma.count(a[i]))a[i]=ma[a[i]];
        else ma[a[i]]=++dd,a[i]=dd;
        d[i]=a[i];
    }
    block=ceil(pow(n,2./3));
    int cnt=0;
    int cnt1=0;
    int x,y,z;
    for(int i=1;i<=m;i++){
        x=read(),y=read(),z=read();
        if(x==1)q[++cnt].l=y,q[cnt].r=z,q[cnt].t=cnt1,q[cnt].id=cnt;
        else {
            if(ma.count(z))z=ma[z];
            else ma[z]=++dd,z=dd;
            c[++cnt1].pos=y,c[cnt1].x=z,c[cnt1].o=d[y];d[y]=z;
        }
    }
    int l,r,t;
    l=r=t=0;
    sort(q+1,q+cnt+1,comp);
    for(int i=1;i<=cnt;i++){
        while(r<q[i].r){
            r++;
            add(a[r],1);
        }
        while(l>q[i].l){
            l--;
            add(a[l],1);
        }
        while(r>q[i].r){
            if(r<=n)add(a[r],-1);
            r--;
        }    
        while(l<q[i].l){
            if(l)add(a[l],-1);
            l++;
        }
        while(t<q[i].t){
            ++t;
            int pos=c[t].pos;
            a[pos]=c[t].x;
            if(pos>=l&&pos<=r)add(c[t].o,-1),add(c[t].x,1);
        }
        while(t>q[i].t){
            int pos=c[t].pos;
            a[pos]=c[t].o;
            if(pos>=l&&pos<=r)add(c[t].o,1),add(c[t].x,-1);
            t--;
        }
        for(int j=1;j<=1000;j++){
            if(!b[j]){
                ans[q[i].id]=j;
                break;
            }
        }
    }
    for(int i=1;i<=cnt;i++){
        printf("%d\n",ans[i]);
    }
    return 0;
}
View Code