CF round#506 div 3

w[i]表示1ei;a[i]*w[j]+{数的位数是i的集合}mod k=0 是一种解

az=a[i]*w[j]%k;

用map统计[位数][模为x]的个数;

ans+=w[j][(k-az)%k];

注意a[i]为j位并且az=a[i];

k开int 挂了好多点。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+30;
const ll az[11]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000};
map<int,int>mm[11];
ll n,k,cnt[11];
ll ans;
struct re{
 ll a;
 int b;
};
re a[N];
int main(){
    //freopen("p.in","r",stdin);
    cin>>n>>k;
    for(int i=1;i<=n;i++){
    scanf("%d",&a[i].a);
    register int s=a[i].a;
    for(int j=1;j<=10;j++)
    if(s/az[j]==0&&s/az[j-1]!=0){
    mm[j][s%k]++;a[i].b=j;break;} 
} 
    for(int i=1;i<=n;i++)
     for(int j=1;j<=10;j++){
     ll mo=a[i].a;
     for(int kk=1;kk<=j;kk++)mo=(mo*10)%k;
     int qq=(k-mo)%k;
     ans=ans+mm[j][qq];
     if(a[i].b==j&&(a[i].a%k)==qq)ans--;
     }
     cout<<ans;
    return 0;
} 
View Code

E 贪心

建树,深度从大到小排序。每次链接根与深度最大的父亲,删除这个父亲和他相连的点。

路径<=2默认删除。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+30;//ֹ�� 
int ans,n,tot,f[N],fai[N],j[N];
struct re{
    int a;     
    int b;    
};
re q[N],edge[N*2]; 
bool cmp(re x,re y){return x.a>y.a;}
void dfs(int fath,int son){
    fai[son]=fath;
    q[son].a=q[fath].a+1;
    q[son].b=son;
    if(q[son].a<4)j[son]=1;
    int k=f[son];
    while(k!=-1){
    int x=edge[k].a;        
    if(!q[x].a)dfs(son,x);
    k=edge[k].b;
    }
}
int main(){
    //freopen("p.in","r",stdin);
    cin>>n;
    for(int i=1;i<=n;i++)f[i]=-1;
    for(int i=1;i<n;i++){
        int u;
        tot++;
        cin>>u>>edge[tot].a;
        edge[tot].b=f[u];
        f[u]=tot;
        tot++;
        edge[tot].a=u;
        edge[tot].b=f[edge[tot-1].a];
        f[edge[tot-1].a]=tot;
}
    dfs(0,1);
    int ax;
    sort(q+1,q+1+n,cmp);
    for(int i=1;i<n;i++)if(!j[q[i].b]){
    ans++;
    int qq=q[i].b;
    int az=fai[qq];
    int k=f[az];
    while(k!=-1){int x=edge[k].a;
    j[x]=1;k=edge[k].b;}
    j[fai[az]]=1;
    j[az]=1;
    }
    cout<<ans;
    return 0;
} 
View Code

F

D1表示大于等于sqrt(a)的因子从小到大排序 ,cnta为此类因子的个数

首先枚举(a+b)可能组成的矩形 

i<j,i*j=a+b;

i=1 to sqrt(a+b)//即i递增,j递减。

我们可以发现

如果当前的j都小于的d1[x],那么之后肯定无法满足d1[x]<=j.

所以我们从大到小枚举d1[x];

d1[x]只会改变cnta次

复杂度为sqrt(a+b).

tip:全部开 long long 就过了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=3e6;
ll az,cnt1,cnt2,a[N],b[N],l,r,ans;
int main()
{    
    //freopen("p.in","r",stdin);
    cin>>l>>r;
    az=l+r;
    ans=az*2+2;
    for(ll i=1;i*i<=l;i++)    if(l%i==0){cnt1++;a[cnt1]=l/i;}
    reverse(a+1,a+1+cnt1);
    for(ll i=1;i*i<=r;i++)
         if(r%i==0){cnt2++,b[cnt2]=r/i;}
    reverse(b+1,b+1+cnt2);
    int asd;
    for(ll i=1;i*i<=az;i++)
    if(az%i==0){
    ll ax=az/i;
    while(a[cnt1]>ax&&cnt1>0)cnt1--;
    if(a[cnt1]*i>=l)ans=min(ans,2*(ax+i));
    while(b[cnt2]>ax&&cnt2>0)cnt2--;
    if(b[cnt2]*i>=r)ans=min(ans,2*(ax+i));
    }
    cout<<ans;
    return 0;
}
View Code

 

posted @ 2018-08-29 10:07  周栎  阅读(155)  评论(0编辑  收藏  举报