D
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; }
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; }
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; }