网赛的时候就是前三个小时过了后面五道,然后两个小时就没搞出啥了;账号密码都忘了,只好重新写一遍了;
hdu-5868
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); #define ll long long; typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=1e6+2000; const int maxn=2e4+50; const double eps=1e-8; int vis[maxn],b[maxn],cnt=0,prime[maxn]; inline void Init() { cnt=0; for(int i=2;i<maxn;i++) { if(!vis[i]) { for(int j=2*i;j<maxn;j+=i)vis[j]=1; prime[++cnt]=i; } } } int phi(int x) { int ans=x; for(int i=1;i<=cnt;i++) { if(x<prime[i])break; if(x%prime[i]==0) { ans=ans/prime[i]*(prime[i]-1); while(x%prime[i]==0)x/=prime[i]; } } if(x>1)ans=ans/x*(x-1); return ans; } LL powmod(LL x,LL y) { LL s=1,base=x; while(y) { if(y&1)s=s*base%mod; base=base*base%mod; y>>=1; } return s; } struct matrix { LL a[2][2]; }; matrix cal(matrix A,matrix B) { matrix C; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { C.a[i][j]=0; for(int k=0;k<2;k++) { C.a[i][j]+=A.a[i][k]*B.a[k][j]; C.a[i][j]%=mod; } } } return C; } LL pow_mod(int y) { matrix s,base; s.a[0][0]=s.a[1][1]=1;s.a[0][1]=s.a[1][0]=0; base.a[0][0]=base.a[0][1]=base.a[1][0]=1;base.a[1][1]=0; while(y) { if(y&1)s=cal(s,base); base=cal(base,base); y>>=1; } return (s.a[0][0]*3+s.a[0][1])%mod; } LL solve(int x) { if(x==1)return 1; else if(x==2)return 3; else return pow_mod(x-2); } int main() { int n; Init(); while(scanf("%d",&n)!=EOF) { if(n==1){printf("2 ");continue;} int le=(int)sqrt(n*1.0+0.5),num=0; for(int i=1;i<=le;i++) { if(n%i==0) { b[++num]=n/i; if(b[num]*b[num]==n)continue; b[++num]=i; } } LL ans=0; for(int i=1;i<=num;i++) { ans=(ans+phi(n/b[i])*solve(b[i]))%mod; } ans=ans*powmod((LL)n,mod-2)%mod; print(ans); } return 0; } /* 题意: https://async.icpc-camp.org/d/546-2016 */
hdu-5869
hdu-5870
hdu-5871
hdu-5872
hdu-5873
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); #define ll long long; typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e4+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=1e6+2000; const int maxn=2e4+50; const double eps=1e-8; int a[maxn]; int main() { int m; while(scanf("%d",&m)!=EOF) { For(i,1,m) { int n,flag=1; LL sum=0; scanf("%d",&n); For(i,1,n)scanf("%d",&a[i]); sort(a+1,a+n+1); for(int i=1;i<n;i++) { sum=sum+a[i]; if(sum<(LL)i*(i-1))flag=0; } sum=sum+a[n]; if(sum!=(LL)n*(n-1))flag=0; if(flag)printf("T "); else printf("F "); } } return 0; } /* 题意: 赢了得两分,平局得一分,输了的分,问得分情况是否符合实际; 思路: 排序后看是否满足这种游戏的要求;读入挂不知怎么T了; */
hdu-5874
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); #define ll long long; typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=1e6+2000; const int maxn=2e4+50; const double eps=1e-8; int main() { LL n,m; while(cin>>n>>m) { LL a=n/2,b=(n+1)/2; if(a*b>m)printf("F "); else printf("T "); } return 0; } /* 题意: */
hdu-5875
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); #define ll long long; typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=1e6+2000; const int maxn=1e5+50; const double eps=1e-8; int n,m,a[maxn],d[maxn][23]; inline void rmq() { for(int i=0;i<n;i++)d[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)<=n;i++) d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]); } inline int query(int L,int R) { int k=0; while((1<<(k+1))<=R-L+1)k++; return min(d[L][k],d[R-(1<<k)+1][k]); } inline void solve(int u,int v) { int temp=a[u]; u++; while(u<=v) { int l=u,r=v; while(l<=r) { int mid=(l+r)>>1; int t=query(u,mid); if(t>temp)l=mid+1; else r=mid-1; } if(l>v)break; if(a[l])temp%=a[l]; if(temp==0) { printf("0 "); return ; } u=l+1; } printf("%d ",temp); } int main() { int t; read(t); while(t--) { read(n); for(int i=0;i<n;i++)read(a[i]); rmq(); read(m); int l,r; while(m--) { read(l);read(r); l--;r--; solve(l,r); } } return 0; } /* 题意: 给一个数列,然后问[l,r]内这些数%得到多少; 思路: 比赛的时候队友用线段树A的,我现在写的是二分+rmq,就是让着里面的数递减才能改变它的结果; */
hdu-5876
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); #define ll long long; typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=1e6+2000; const int maxn=2e5+50; const double eps=1e-8; int n,m,ans[maxn]; pair<int,int>p; map<pair<int,int>,int>mp; queue<int>q,qu; inline void makepair(int u,int v) { p.first=u; p.second=v; mp[p]=1; } int main() { int t; read(t); while(t--) { mp.clear(); read(n);read(m); int u,v,s; For(i,1,m) { read(u);read(v); makepair(u,v); makepair(v,u); } read(s); while(!q.empty())q.pop(); while(!qu.empty())qu.pop(); For(i,1,n) { if(s==i)continue; qu.push(i); } q.push(s); ans[s]=0; while(!q.empty()) { int fr=q.front(); q.pop(); int siz=qu.size(); p.first=fr; while(siz--) { int f=qu.front(); qu.pop(); p.second=f; if(!mp[p])ans[f]=ans[fr]+1,q.push(f); else qu.push(f); } } int num=0; For(i,1,n) { if(i==s)continue; num++; if(num<n-1)printf("%d ",ans[i]); else printf("%d ",ans[i]); } } return 0; } /* 题意: 求一个点多边少的补图的一个起点到其他所有点的最短距离; 思路: 补图里面的边就是原图里面没有的边,那么每次就判断两个点之间在原图中是否有边,主要是原图里面边较少可以这样判断; */
hdu-5877
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); #define ll long long; typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=1e6+2000; const int maxn=2e5+50; const double eps=1e-8; int a[maxn],b[maxn],c[maxn],cnt,sum[maxn],in[maxn],n; LL k,ans; vector<int>ve[maxn]; int lowbit(int x){return x&(-x);} inline int query(int x) { int s=0; while(x) { s+=sum[x]; x-=lowbit(x); } return s; } inline void update(int x,int num) { while(x<=cnt) { sum[x]+=num; x+=lowbit(x); } } inline int getpos(LL x) { int l=1,r=cnt; while(l<=r) { int mid=(l+r)>>1; if((LL)c[mid]>x)r=mid-1; else l=mid+1; } return r; } void dfs(int cur) { int pos; if(a[cur]==0)pos=cnt; else pos=getpos(k/a[cur]); ans=ans+query(pos); int temp=getpos(a[cur]); update(temp,1); int len=ve[cur].size(); for(int i=0;i<len;i++)dfs(ve[cur][i]); update(temp,-1); } int main() { int t; read(t); while(t--) { read(n);read(k); For(i,0,n) { ve[i].clear(); sum[i]=in[i]=0; } For(i,1,n)read(a[i]),b[i]=a[i]; sort(b+1,b+n+1); c[1]=b[1];cnt=1;ans=0; For(i,2,n) { if(b[i]==b[i-1])continue; c[++cnt]=b[i]; } int u,v,root; For(i,1,n-1) { read(u);read(v); ve[u].push_back(v); in[v]++; } For(i,1,n) { if(in[i])continue; root=i; break; } dfs(root); print(ans); } return 0; } /* 题意: 求每个节点u以及和它的祖先节点v满足a[u]*a[v]<=k的对数和; 思路: dfs的过程中将树状数组中保留的是它的所有祖先节点的信息,可以离散化后进行询问, 然后把这个点的信息更细到树状数组中,待它的所有节点都访问完了再删除,据说treap也可以做; */