【BZOJ4927】第一题 双指针+DP

题解:

虽然是过了,不过做的十分智障

首先是有 2根 2 1 1 , 3根 1 1 1

这两种方法

然后考虑2 2 1 1

two-point-two没啥好说的

3 1 1 1

我很智障的以为数据范围是1e9

然后写了hash,刚开始还开错范围

把int换short int才卡过了空间

首先枚举 1 1 1

然后枚举3 中的一条边

既然1e7直接记录每个数能由两个数组成的方案数

另外再减去这条边参与的方案数(直接两个数减一下查有几个就好了)

然后细节还挺多的搞个对拍就可以了

#pragma G++ optimize (2)
#include <bits/stdc++.h>
using namespace std;
#define N 6000
#define rg register
#define IL inline
#define ll long long
int a[N],n;
unsigned ll ans,ans3;
#define js(x) x*(x-1)/2*(x-2)/3*(x-3)/4
const int mo1=1.3e7+;
const int NN=1.3e7+1e5;
const int mo2=2.6e7+;
const int N2=2.6e7+1e5;
int hash1[NN],hash2[NN],hash4[N2];
short int hash3[N2],hash5[N2];
char ss[<<],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;}
template<class T>void read(T&x){
rg int f=,c;while(c=gc(),c<||<c)if(c=='-')f=-;x=c^;
while(c=gc(),<c&&c<)x=(x<<)+(x<<)+(c^);x*=f;
}
IL void push(int x)
{
int y=x%mo1;
while (hash1[y]&&hash1[y]!=x) y++;
hash1[y]=x; hash2[y]++;
}
IL int find1(int x)
{
int y=x%mo1;
while (hash1[y]&&hash1[y]!=x) y++;
if (hash1[y]==x) return(hash2[y]);
else return();
}
IL void push2(int x,int y)
{
int z=(1ll*y*+x)%mo2;
while (hash3[z]&&!(hash3[z]==x&&hash4[z]==y)) z++;
hash3[z]=x; hash4[z]=y; hash5[z]++;
}
IL int find2(int x,int y)
{
int z=(1ll*y*+x)%mo2;
while (hash3[z]&&!(hash3[z]==x&&hash4[z]==y)) z++;
if (hash3[z]==x&&hash4[z]==y) return(hash5[z]);
else return();
}
IL bool cmp(int a,int b)
{
return(a<b);
}
int now,cnt;
#define INF 1e9
int main()
{
freopen("noi.in","r",stdin);
freopen("noi.out","w",stdout);
read(n);
for (rg int i=;i<=n;i++) read(a[i]);
sort(a+,a+n+,cmp);
for (rg int i=;i<=n;i++)
for (rg int j=i+;j<=n;j++)
push(a[i]+a[j]);
a[]=INF;
for (rg int i=;i<=n;i++)
for (rg int j=i+;j<=n;j++)
push2(i,a[i]+a[j]),push2(j,a[i]+a[j]);
now=;
while (++now<=n)
{
cnt=;
while (now<n&&a[now+]==a[now]) cnt++,now++;
if (cnt>=)
{
int h=,t=n;
ll ans2=;
while (h<t)
{
int h1=h,t1=t;
while (a[h]==a[h+]&&h<t) h++;
while (a[t]+a[h]>a[now]&&h<t) t--;
if (a[t]+a[h]!=a[now])
{
h++;
continue;
}
t1=t;
while (a[t]==a[t-]&&h<t) t--;
if (h==t)
{
int xx=t1-h1+;
if (t1-h1+>=) ans+=1ll*cnt*(cnt-)/*js(xx);
ans+=1ll*ans2*cnt*(cnt-)/*(t1-h1+)*(t1-h1)/;
break;
}
if (h-h1>=&&t1-t>=)
{
ans+=1ll*cnt*(cnt-)/*(h-h1)*(h-h1+)/*(t1-t)*(t1-t+)/;
}
ans+=1ll*cnt*(cnt-)/*ans2*(t1-t+)*(h-h1+);
ans2+=(t1-t+)*(h-h1+);
h++;
}
}
if (cnt>=)
{
rg ll ans2=1ll*cnt*(cnt-)*(cnt-)/;
unsigned rg ll ans4=;
for (rg int i=;i<=n;i++)
{
if (a[now]>a[i])
{
int x=find1(a[now]-a[i]);
int y=find2(i,a[now]-a[i]);
ans4+=1ll*(x-y)*ans2;
}
}
ans3+=ans4/;
}
}
//ans3/=3;
cout<<ans+ans3<<endl;
return ;
}

对拍 n^6

#include <bits/stdc++.h>
using namespace std;
#define rg register
#define N 10000
#define rep(i,x,y) for (rg int i=x;i<=y;i++)
int b[];
bool cmp(int x,int y)
{
return(x<y);
}
int a[N],n;
bool pd1(int x1,int x2,int x3,int x4,int x5,int x6)
{
b[]=a[x1],b[]=a[x2],b[]=a[x3],b[]=a[x4],b[]=a[x5],b[]=a[x6];
sort(b+,b++,cmp);
if (b[]+b[]==b[]+b[]&&b[]+b[]==b[]&&b[]==b[])
return(); else return();
}
bool pd2(int x1,int x2,int x3,int x4,int x5,int x6)
{
b[]=a[x1],b[]=a[x2],b[]=a[x3],b[]=a[x4],b[]=a[x5],b[]=a[x6];
sort(b+,b++,cmp);
if (b[]+b[]+b[]==b[]&&b[]==b[]&&b[]==b[])
return(); else return();
}
int main()
{
freopen("noi.in","r",stdin);
freopen("noi2.out","w",stdout);
std::ios::sync_with_stdio(false);
cin>>n;
for (int i=;i<=n;i++) cin>>a[i];
int cnt=,cnt2=;
rep(i1,,n)
rep(i2,i1+,n)
rep(i3,i2+,n)
rep(i4,i3+,n)
rep(i5,i4+,n)
rep(i6,i5+,n)
if (pd1(i1,i2,i3,i4,i5,i6))
{ cnt++;
}
rep(i1,,n)
rep(i2,i1+,n)
rep(i3,i2+,n)
rep(i4,i3+,n)
rep(i5,i4+,n)
rep(i6,i5+,n)
if (pd2(i1,i2,i3,i4,i5,i6))
{
// cout<<i1<<" "<<i2<<" "<<i3<<" "<<i4<<" "<<i5<<" "<<i6<<endl;
cnt++;
}
cout<<cnt+cnt2<<endl;
return ;
}
上一篇:模糊查询(LIKE)and (PATINDEX() . CHARINDEX())


下一篇:并查集---java模板