【除草】一些稍难题
来源:互联网 发布:pdf acrobat pro mac 编辑:程序博客网 时间:2024/04/28 14:09
hdu4623
通过打表发现很多数字在考虑互质的情况是等价的,因此将其压成同一种数字,最后再乘以排列数就可以状压dp了
一开始判等价的时候,没有考虑可以不用比较自身,导致算出来的状态有500W+,实际上只有200W不到
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <string>#include <ctime>using namespace std;int n,m,g[30][30],D[30],d[30],lim,u[30],cnt,p[30],q[30],C[30];short f[5600000][29];int t,mo;int gcd(int a,int b){for (;a%b;) {int t=a%b;a=b;b=t;}return b;}bool cmp(int i,int j,int n){for (int k=1;k<=n;k++)if (i!=k && j!=k) {if ((gcd(i,k)==1 && gcd(j,k)!=1)) return 1;else if ((gcd(i,k)!=1 && gcd(j,k)==1)) return 1;}return 0;}void origin(int n){C[1]=1;for (int i=2;i<=n;i++) C[i]=(C[i-1]*i)%mo;for (int i=1;i<=n;i++) d[i]=0,u[i]=0;for (int i=1;i<=n;i++) {for (int j=1;j<=n;j++)if (gcd(i,j)==1) {g[i][j]=1; }}cnt=0;lim=1;for (int i=1;i<=n;i++)if (!u[i]) {q[++cnt]=i,p[i]=cnt;d[cnt]=1;for (int j=i+1;j<=n;j++)if (!cmp(i,j,n)) u[j]=1,d[cnt]++;lim*=(d[cnt]+1);}D[0]=1;for (int i=1;i<=cnt;i++)D[i]=D[i-1]*(d[i]+1);}inline bool check(int s,int i){return (s/D[i-1])%(d[i]+1);}inline int change(int s,int i){return s-=(1*D[i-1]);}int main(){freopen("input.txt","r",stdin);scanf("%d",&t);for (;t;t--) {scanf("%d%d",&n,&mo);origin(n);//cout<<lim<<endl;for (int s=1;s<lim;s++)for (int j=1;j<=cnt;j++)if (check(s,j)) {int ns=change(s,j);if (!ns) {f[s][j]=1;continue;}f[s][j]=0;for (int k=1;k<=cnt;k++)if (g[q[j]][q[k]] && check(ns,k)) {f[s][j]=((int)f[s][j]+f[ns][k])%mo;}}int ans=0;for (int i=1;i<=cnt;i++)ans=(ans+f[lim-1][i])%mo;for (int i=1;i<=cnt;i++)ans=(ans*C[d[i]])%mo;printf("%d\n",ans);//cout<<lim<<endl;}//cout<<clock()<<endl;return 0;}
hdu3761
删连续一段点一定更优
发现了半平面交模板的一个漏洞(不过反正是自己写的模板,有问题也正常╮(╯▽╰)╭),似乎以前判无解的情况很少,这次就出问题了
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>#define sqr(x) ((x)*(x))const long double eps=1e-6;const long double pi=acos(-1.0);const long double oo=1e15;using namespace std;struct point{ long double x,y,z,_,d; void print() {// printf("x=%lf y=%lf z=%lf\n",x,y,z); //cout<<"x= "<<x<<" y= "<<y<<" z= "<<z<<endl; cout<<x<<"x+"<<y<<"y>"<<-z<<endl; }}a[500000],p[500000],St[500000];int u[500000],st[500000],U[500000];int n;inline long double cr(point &e,point &r) {return e.x*r.y-e.y*r.x;}inline long double dot(point &e,point &r) {return e.x*r.x+e.y*r.y+e.z*r.z;}inline void cross(point p,point q,point &e){ e.x=p.y*q.z-p.z*q.y; e.y=p.z*q.x-p.x*q.z; e.z=p.x*q.y-p.y*q.x;}inline void ori(point &a){ a._=atan2(a.y,a.x); a.d=a.z/sqrt(sqr(a.x)+sqr(a.y));}inline bool cmp(int i,int j){ long double tmp=p[i]._-p[j]._; if (fabs(tmp)>pi/2) return tmp<-eps; tmp=cr(p[i],p[j]); if (fabs(tmp)>eps) return tmp>eps; return p[i].d<p[j].d;}inline bool check(point &p,point I){ if (dot(p,I)>eps) return 1; return 0;}inline bool equ(point &p) {return fabs(p.x)<eps && fabs(p.y)<eps && fabs(p.z)<eps;}bool check(int ans){ if (ans==n) return 1; int tot=0; ++tot,p[tot].x=0,p[tot].y=-1,p[tot].z=oo; ++tot,p[tot].x=1,p[tot].y=0,p[tot].z=oo; ++tot,p[tot].x=0,p[tot].y=1,p[tot].z=oo; ++tot,p[tot].x=-1,p[tot].y=0,p[tot].z=oo; for (int i=n+n;i>=n+1;i--) { point A=a[i-1],B=a[i+ans]; point l; cross(A,B,l); if (dot(l,a[i])>-eps) { l.x=-l.x,l.y=-l.y,l.z=-l.z; } p[++tot]=l; } for (int i=1;i<=tot;i++) ori(p[i]),U[i]=i; int op=5; for (int i=6;i<=tot;i++) if (cmp(i,op)) op=i; for (int i=5;i<op;i++) U[++tot]=U[i]; int cnt=0; for (int i=1,j=op;i<=4 || j<=tot;) { if ((i>4) || cmp(U[i],U[j]) || j>tot) { u[++cnt]=U[i]; i++; } else { u[++cnt]=U[j]; j++; } }// for (int i=1;i<=cnt;i++) cout<<u[i]<<' ';cout<<endl;// sort(u+1,u+cnt+1,cmp);// for (int i=1;i<=cnt;i++) cout<<u[i]<<' ';cout<<endl; int h,r; st[h=r=1]=u[1]; for (int i=2;i<=cnt;i++) { if (fabs(cr(p[u[i]],p[u[i-1]]))<eps) continue; for (;(h<r) && (!check(St[r],p[u[i]]));r--) ; for (;(h<r) && (!check(St[h+1],p[u[i]]));h++) ; st[++r]=u[i]; cross(p[st[r-1]],p[st[r]],St[r]); if (equ(St[r])) return 1; } for (;(h<r) && (!check(St[r],p[st[h]]));r--) ; for (;(h<r) && (!check(St[h+1],p[st[r]]));h++) ; //cout<<h<<' '<<r<<endl; for (int i=h;i<=r;i++) if (st[i]<=4) return 1; return r-h+1<=2;}int main(){ int t; scanf("%d",&t); for (;t;t--) { scanf("%d",&n); for (int i=1;i<=n;i++) { double x,y; scanf("%lf%lf",&x,&y),a[i].z=1; a[i].x=x,a[i].y=y; a[i+n]=a[i],a[i+n+n]=a[i]; } int l=1,r=n-3; for (;l<=r;) { int mid=(l+r)>>1; if (check(mid)) r=mid-1; else l=mid+1; } printf("%d\n",l); } return 0;}
hdu3983
询问某一位为1,即取模后按剩余系询问一段区间。
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <set>using namespace std;multiset < long long > Set;int f[20][1<<20];int q,t;char ch[20000];void origin(){ for (int i=0;i<=17;i++) for (int j=0;j<=((1<<(i+1))-1)+1;j++) f[i][j]=0;}void change(int e,int x,int cnt){ x+=1; int lim=((1<<(e+1))-1)+1; for (;x<=lim;x+=(x & (-x))) f[e][x]+=cnt;}int ask(int e,int x){ int sum=0; x+=1; for (;x;x-=(x & (-x))) sum+=f[e][x]; return sum;}int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d",&t); for (int test=1;t;t--,test++) { printf("Case %d:\n",test); scanf("%d",&q); origin(); long long bj=0; Set.clear(); for (int i=1;i<=q;i++) { scanf("%s",ch+1); long long x; int xx; if (ch[1]=='I') { scanf("%d",&xx);x=xx; x-=bj; Set.insert(x); for (int j=0;j<=17;j++) { int y=(x&((1<<(j+1))-1)); change(j,y,1); } } else if (ch[1]=='D') { scanf("%d",&xx);x=xx; x-=bj; int cnt=Set.count(x); if (!cnt) { printf("Del error\n"); continue; } Set.erase(x); for (int j=0;j<=17;j++) { int y=(x&((1<<(j+1))-1)); change(j,y,-cnt); } if (!Set.size()) bj=0; } else if (ch[1]=='A') { scanf("%d",&xx);x=xx; bj+=x; } else if (ch[1]=='S') { scanf("%d",&xx);x=xx; if (!Set.size()) continue; if (!Set.size() || (*Set.begin())+bj-x<0) { printf("Sub error\n"); continue; } bj-=x; } else if (ch[1]=='Q' && ch[2]=='N') { scanf("%d",&xx);x=xx; x-=bj; int ans=Set.count(x); printf("%d\n",ans); } else if (ch[1]=='Q' && ch[2]=='B') { scanf("%d",&xx);x=xx; long long l=((1<<x)-1),r=((1<<(x+1))-1); int mo=(1<<(x+1)); l=((l-bj)%mo+mo)%mo,r=((r-bj)%mo+mo)%mo; if (l<=r) { int ans=ask(x,r)-ask(x,l); printf("%d\n",ans); } else { int ans=(ask(x,mo-1)-ask(x,l))+ask(x,r); printf("%d\n",ans); } } } printf("\n"); } return 0;}
poj 3851
特殊的最短路,有负圈,但是负圈在当前距离小于某个值的时候就会消失,因此每次把负圈抽出来处理一下,有点像消圈算法。
#include<cstdio>#include<cmath>#include<algorithm>#include<iomanip>#include<iostream>#include<ctime>const int oo=1073741819;using namespace std;int n,m,cnt;struct point{ int x,y,z,t; void scan() { scanf("%d%d%d",&x,&y,&z); t=-oo; }}p[1010];struct worm{ int a,b; int t,d;}w[1010];int f[1010];const int maxn=1000000;int q[maxn+10],t[1010];bool vis[1010];int pre[1010];double sqr(double x){ return x*x;}int dis(point a,point b){ double d=sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z)); return (int)(ceil(d));}int st[1010],Rd[1010],loc[1010],w_time,pra[1010],D[1010][1010];void doit(int s,int &head,int &tail){ int r=0; int k=-oo; w_time++; int i; for (i=s;Rd[i]!=w_time;i=pre[i]) { Rd[i]=w_time; st[++r]=i; loc[i]=r; } int op=loc[i],cf=0; for (int i=op;i<=r;i++) { if (p[st[i]].t>k) k=p[st[i]].t,cf=i; } if (k==-oo || k>=f[st[cf]]) return ; int dis=p[st[cf]].t; f[st[cf]]=min(f[st[cf]],dis); for (int i=cf-1;i>=op;i--) { dis+=pra[st[i]];if (dis<f[st[i]]) {f[st[i]]=min(f[st[i]],dis);if (!vis[st[i]]) {tail=tail%maxn+1; q[tail]=st[i]; t[st[i]]++; vis[st[i]]=true;}}} for (int i=r;i>cf;i--) { dis+=pra[st[i]];if (dis<f[st[i]]) {f[st[i]]=min(f[st[i]],dis);if (!vis[st[i]]) {tail=tail%maxn+1; q[tail]=st[i]; t[st[i]]++; vis[st[i]]=true;}} }}void work(){ p[1].scan(); p[2].scan(); scanf("%d",&n); cnt=2; for (int i=1;i<=n;i++) { p[++cnt].scan(); w[i].a=cnt; p[++cnt].scan(); w[i].b=cnt; scanf("%d%d",&w[i].t,&w[i].d); p[cnt-1].t=w[i].t; //p[cnt].t=w[i].t+w[i].d; } for (int i=1;i<=cnt;i++) for (int j=i+1;j<=cnt;j++) { D[i][j]=D[j][i]=dis(p[i],p[j]);// cout<<i<<' '<<j<<' '<<D[i][j]<<endl; } for (int i=1;i<=cnt;i++) vis[i]=false,f[i]=oo,t[i]=0,pre[i]=0,pra[i]=0; int head=1,tail=1; vis[1]=true;t[1]=1; f[1]=0; q[1]=1; while (head!=tail+1) { int x=q[head]; vis[x]=false; head=head%maxn+1; if (t[x]>=cnt) { doit(x,head,tail); } for (int i=1;i<=cnt;i++) if (f[i]>f[x]+D[x][i]) { f[i]=f[x]+D[x][i]; pre[i]=x,pra[i]=D[x][i]; if (!vis[i]) { tail=tail%maxn+1; q[tail]=i; t[i]++; vis[i]=true; } } for (int i=1;i<=n;i++) { int dd=0; if (x!=w[i].a) continue; dd=max(f[x],w[i].t); if (f[w[i].b]>dd+w[i].d) { f[w[i].b]=dd+w[i].d; pre[w[i].b]=x,pra[w[i].b]=w[i].d; if (!vis[w[i].b]) { vis[w[i].b]=true; tail=tail%maxn+1; t[w[i].b]++; q[tail]=w[i].b; } } } // vis[x]=false; } //for (int i=1;i<=cnt;i++) cout<<f[i]<<' ';cout<<endl; printf("%d\n",f[2]);}int main(){ freopen("J.in","r",stdin); freopen("output.txt","w",stdout); int times; scanf("%d",×); for (int i=1;i<=times;i++) work(); return 0;}
0 0
- 【除草】一些稍难题
- 【除草】一些题目
- 除草记
- 开张除草
- 【codechef除草】
- 遇到一些技术难题
- 今天来blog除草!!
- Hi系列之,除草
- 2011除草-rbuttondown调用
- 要除草了
- 【除草】Hackerrank思考题
- 除草(3.30~4.4)
- 除草(4.6~4.11)
- [论文除草]记录思路
- 2187. 猴子除草
- cocoapods安装遇到的一些小难题!
- [挖矿]BZOJ 第一页 除草
- 难题
- java HttpClient get post请求 调用接口
- 创新实验室实习生每周工作总结【实习第十五周】
- 基于样本一致性的背景减除运动目标检测算法(SACON)
- 【安卓】数据库基于脚本的"增量更新",每次更新时不需修改java代码、!
- hdu 1492 The number of divisors(约数) about Humble Numbers (数学:排列组合)
- 【除草】一些稍难题
- SciPy--数值计算
- shell定时任务,10执行一次
- C#的矩阵类
- sencha touch 搜索功能search的实现
- 设计原则
- linux编程思想
- SciPy和Numpy处理能力
- 重排数组元素,奇数放在奇数位,偶数放在偶数位