全队就我一开始敲出了一道签到题1007The Unsolvable Problem。。。之后就各种被虐啊。。。
没算法,只能说是YY出来的。题意就是让你求出n=a+b,a和b的最大的最小公倍数,首先考虑奇数,当奇数被拆为n=x+(x+1)时,x和(x+1)为互质数,直接相乘得到答案,而偶数的话,2直接特判==1,再看其它偶数,当偶数除以2为奇数时,上下加减1肯定为两个偶数,最小公倍数必然不能取最大,所以应上下加减2,然后相乘得到答案。而当偶数除以2为偶数时,上下加减1互为奇数(互质),然后相乘得到答案。
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdio>
using namespace std;
int main()
{
int t;
__int64 n;
cin>>t;
while(t--)
{
cin>>n;
if(n==2)
{
cout<<1<<endl;
continue;
}
if(n%2==1)
{
cout<<(n/2)*(n/2+1)<<endl;
}
else
{
if((n/2)%2==0)
{
cout<<(n/2-1)*(n/2+1)<<endl;
}
else
{
cout<<(n/2-2)*(n/2+2)<<endl;
}
}
}
return 0;
}
1011 Sad Love Story
比赛中后期一直在敲这题,发现是个求多次最近点对的问题,一开始用分治法求,O(n^2logn),复杂度太高TLE,后来学长写了KD-tree,发现还是TLE,赛后看标程才理解了,不需要求多次,先求一次全部点的最近点对,对于之前的点就不需要算了,然后去掉了一部分点,直到找到最后点为止。解题报告说KD-tree也可以做,但是要常数优化,表示不懂。。。。
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdio>
#define MAXN 500010
using namespace std;
struct xl
{
long long x,y,id,in;
xl(long long xx=0,long long yy=0,long long iin=0)
{
x=xx;
y=yy;
in=iin;
}
}P[MAXN],p[MAXN],tmpt[MAXN];
struct zx
{
long long f,s;
}e;
long long dd(xl a,xl b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp1(xl a,xl b)
{
if(a.x != b.x)
{
return a.x<b.x;
}
else
{
return a.y<b.y;
}
}
bool cmp2(xl a,xl b)
{
return a.y<b.y;
}
zx XLL(long long lw,long long hi)
{
int i,j,k;
long long d=(1LL<<60),mid,d1,d2;
if(lw==hi)
{
e.f=lw;
e.s=hi;
return e;
}
if(lw+1==hi)
{
e.f=lw;
e.s=hi;
return e;
}
mid=(lw+hi)/2;
zx pr1=XLL(lw,mid);
zx pr2=XLL(mid+1,hi);
if(pr1.f==pr1.s)
{
d1=(1LL<<60);
}
else
{
d1=dd(p[pr1.f],p[pr1.s]);
}
if(pr2.f==pr2.s)
{
d2=(1LL<<60);
}
else
{
d2=dd(p[pr2.f],p[pr2.s]);
}
zx ans;
if(d1<d2)
{
ans=pr1;
}
else
{
ans=pr2;
}
d=min(d1,d2);
k=0;
for(i=lw; i<=hi; i++)
{
if((p[mid].x-p[i].x)*(p[mid].x-p[i].x)<=d)
{
tmpt[k++]=p[i];
}
}
sort(tmpt,tmpt+k,cmp2);
for(i=0; i<k; i++)
{
for(j=i+1; j<k&&(tmpt[j].y-tmpt[i].y)*(tmpt[j].y - tmpt[i].y) < d; j++)
{
if(d>dd(tmpt[i],tmpt[j]))
{
d=dd(tmpt[i],tmpt[j]);
ans.f=tmpt[i].id;
ans.s=tmpt[j].id;
}
}
}
return ans;
}
int main()
{
int t,i;
long long n,ax,ay,bx,by,cx,cy,w,Max,x,y,ans;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&n,&ax,&bx,&cx,&ay,&by,&cy);
P[0]=xl(0,0,0);
for(i=1; i<=n; i++)
{
x=(P[i-1].x*ax+bx)%cx;
y=(P[i-1].y*ay+by)%cy;
P[i]=xl(x,y,i);
}
w=n;
ans=0;
while(w>1)
{
for(i=0; i<w; i++)
{
p[i]=P[i+1];
}
sort(p,p+w,cmp1);
for(i=0; i<w; i++)
{
p[i].id=i;
}
zx pr=XLL(0,w-1);
Max=max(p[pr.f].in,p[pr.s].in);
ans+=(w-Max+1)*dd(p[pr.f],p[pr.s]);
w=Max-1;
}
printf("%I64d\n",ans);
}
return 0;
}
1008 Pieces
版刷题,可我们没过。。。敲了一上午,用状压暴力枚举做得,,,2^16的个数
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdio>
#define MAXN 1<<16
using namespace std;
int dp[MAXN],q[MAXN];
inline void RD(int &ret)
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
int main()
{
int t,i,j,l,l1,f,w;
char a[22];
RD(t);
while(t--)
{
scanf("%s",a);
l=strlen(a);
l1=1<<l;
for(i=1; i<l1; ++i)
{
dp[0]=MAXN;//初始化,容易出错。。。
w=0;
for(j=0; j<=l; ++j)
{
if(i&(1<<j))
{
q[w++]=j;
}
}
f=0;
w=w-1;
for(j=0; j<w/2; ++j)
{
if(a[q[j]]!=a[q[w-j]])
{
dp[i]=w+1;
f=1;
break;
}
}
if(f==0)
{
dp[i]=1;
}
for(j=i;j;j=(j-1)&i)
{
//cout<<(j^i)<<' '<<dp[(j^i)]<<endl;
dp[i]=min(dp[i],dp[j]+dp[j^i]);
}
//cout<<dp[i]<<endl;
}
printf("%d\n",dp[l1-1]);
}
return 0;
}
加了个输入优化。。
1010 No Pain No Game
树状数组维护,数据结构的题表示一直不太会,而且也看不太出来。。。
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
#include<cstdio>
using namespace std;
int n,c[50001];
int a[50001],b[50001],ac[50001];
inline void RD(int &ret)//输入优化挺重要
{
char c;
do
{
c=getchar();
}
while(c<'0'||c>'9');
ret=c-'0';
while((c=getchar())>='0'&&c<='9')
{
ret=ret*10+(c-'0');
}
}
int lowbit(int x)
{
return x&(-x);
}
int add(int n)
{
int sum=0;
while(n>0)
{
sum=max(sum,c[n]);
n-=lowbit(n);
}
return sum;
}
void updata(int i,int x)
{
while(i<=n)
{
c[i]=max(c[i],x);
i+=lowbit(i);
}
}
struct xl
{
int lw,hi,id;
} s[50001];
bool cmp(xl x,xl y)
{
return x.lw>y.lw;
}
int main()
{
int i,t,m,j,k;
RD(t);
while(t--)
{
RD(n);
for(i=1; i<=n; ++i)
{
RD(a[i]);
}
RD(m);
for(i=0; i<m; ++i)
{
RD(s[i].lw);
RD(s[i].hi);
s[i].id=i;
}
sort(s,s+m,cmp);
i=n;
j=0;
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
while(j<m)
{
for(; i>0&&i>=s[j].lw; --i)
{
for(k=1; k*k<=a[i]; ++k)
{
if(a[i]%k==0)
{
if(b[k]!=0)
{
updata(b[k],k);
}
b[k]=i;
if(a[i]/k!=k)
{
if(b[a[i]/k]!=0)
{
updata(b[a[i]/k],a[i]/k);
}
b[a[i]/k]=i;
}
}
}
}
while(j<m&&s[j].lw>i)
{
ac[s[j].id]=add(s[j].hi);
j++;
}
}
for(i=0; i<m; ++i)
{
printf("%d\n",ac[i]);
}
}
return 0;
}