感觉自己要完
成功被虐了两倍分。。
其实故事是这样的
看了第二题 发现是个SB树分
然后就没有然后了
突然Manchery说自己的代码会被卡常 然后我拿了大样例 没开优化跑了0.8s 时限2s 感觉很稳啊
看了第一题 完全没思路 看了看大样例 我日 SB题。。。 但是要特判几个hack点。。。
第三题 弃疗 暴力都不会。。。
然后。。。本机跑0.8s的我在评测机上2s TLE…
然而本机比我慢的Manchery就就就轻轻松松跑过去了
日 EXM?什么破机子 被卡常了
map真TM的慢。。早知道就不图方便自己打个数组记录
第一题 特判成功没考虑重复情况 成功gg
然后因为蜜汁数据打包问题。。。。
200 -> 70
EXM?200分rank2啊
感觉自己好弱啊QaQ
T1:找规律
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<map>
using namespace std;
#define Com complex<double>
const
double pi=acos(-1);
char c;
#define ll long long
inline void read(ll &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
ll a[100001];
ll P[100001];
const int MAXN=2233333;
int Tot,prime[MAXN+1];
bool ck[MAXN+1];
bool Has[MAXN+1];
int main()
{
for(int i=2;i<=MAXN;i++)
{
if(!ck[i])prime[++Tot]=i;
for(int j=1,k=2*i;j<=Tot&&k<=MAXN;k=prime[++j]*i)
{
ck[k]=true;
if(i%prime[j]==0)break;
}
}
ll n,x;
read(n),read(x);
for(int i=1;i<=n;i++)read(a[i]),Has[a[i]>MAXN?0:a[i]]=true;
sort(a+1,a+1+n);
n=unique(a+1,a+1+n)-a-1;
if(x==2){return puts("0"),0;}
if(a[1]==1){return puts("1"),0;}
if(a[1]!=2){return puts("-1"),0;}
if(x==3){return puts("1"),0;}
if(a[2]!=3){return puts("-1"),0;}
if(n==1){return puts("-1"),0;}
if(prime[n+1]<x){return puts("-1"),0;}
int tot=0;
for(int i=1;prime[i]<x;i++)
{
if(!Has[prime[i]]){return puts("-1"),0;}
tot++;
}
cout<<tot<<endl;
return 0;
}
T2:
Sol1:
O(nlogn)
可持久化线段树加堆
Sol2:
O(nlog2n)
点分树+超级钢琴
Sol3:
O(nlog2n)
点分树+二分答案+Two Pointer累加
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<map>
using namespace std;
#define Com complex<double>
const
double pi=acos(-1);
char c;
inline void read(int&a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Chain
{
int u,len;
Chain*next;
}*Head[100001];
inline void Add(int u,int v,int len)
{
Chain*tp=new Chain;
tp->u=v;
tp->len=len;
tp->next=Head[u];
Head[u]=tp;
}
int All[5000001],Cur;
int SonBG[50001],SonED[50001],SubBG[50001],SubED[50001];
int Size[50001];
bool done[50001];
void GetSize(int u,int f)
{
Size[u]=1;
for(Chain*tp=Head[u];tp;tp=tp->next)
if(tp->u^f&&!done[tp->u])GetSize(tp->u,u),Size[u]+=Size[tp->u];
}
int Rt,MX[50001],SUM;
void GetRoot(int u,int f)
{
MX[u]=SUM-Size[u];
for(Chain*tp=Head[u];tp;tp=tp->next)
if(tp->u^f&&!done[tp->u])
GetRoot(tp->u,u),MX[u]=max(MX[u],Size[tp->u]);
if(MX[Rt]>MX[u])Rt=u;
}
int Cache[50001],tot;
bool Vis[50001];
int M;
void DFS(int u,int f,int Len)
{
Cache[++tot]=Len,M=max(M,Len);
for(Chain*tp=Head[u];tp;tp=tp->next)
if(tp->u^f&&!done[tp->u])
DFS(tp->u,u,Len+tp->len);
}
int Sont;
int F[200001],U[200001];
void Div(int u)
{
done[u]=true;
int t=Cur+1;
for(Chain*tp=Head[u];tp;tp=tp->next)
if(!done[tp->u])
{
tot=0;
DFS(tp->u,u,tp->len);
++Sont;
F[Sont]=u;
U[Sont]=tp->u;
SonBG[Sont]=1+Cur;
for(int i=1;i<=tot;i++)
All[++Cur]=Cache[i];
SonED[Sont]=Cur;
sort(All+SonBG[Sont],All+SonED[Sont]+1);
}
SubBG[u]=Cur+1;
int MX=Cur;
for(int i=t;i<=MX;i++)
All[++Cur]=All[i];
All[++Cur]=0;
SubED[u]=Cur;
sort(All+SubBG[u],All+SubED[u]+1);
for(Chain*tp=Head[u];tp;tp=tp->next)
if(!done[tp->u])
{
GetSize(tp->u,u);
SUM=Size[tp->u];
Rt=0;
GetRoot(tp->u,u);
Div(Rt);
}
}
int n,m;
bool Query(int LEN)
{
int Cnt=0;
for(int i=1;i<=n;i++)
{
int *Data=All+SubBG[i]-1;
int Y=SubED[i]-SubBG[i]+1,MAX=Y,X=Y-1;
if(X<1||Data[X]+Data[Y]<LEN)continue;
while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;
while(X<Y)
{
while(X<Y&&Data[X]+Data[Y]<LEN)X++;
Cnt+=Y-X;
Y--;
}
}
if(Cnt<m)return false;
for(int i=1;i<=Sont;i++)
{
int *Data=All+SonBG[i]-1;
int Y=SonED[i]-SonBG[i]+1,MAX=Y,X=Y-1;
if(X<1||Data[X]+Data[Y]<LEN)continue;
while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;
while(X<Y)
{
while(X<Y&&Data[X]+Data[Y]<LEN)X++;
Cnt-=Y-X;
Y--;
if(Cnt<m)return false;
}
}
return Cnt>=m?true:false;
}
//map<int,int>Val;
inline bool cmp(int a,int b){return abs(a)>abs(b);}
int Val[1000001],P;
void COUT(int LEN)
{
for(int i=1;i<=n;i++)
{
int *Data=All+SubBG[i]-1;
int Y=SubED[i]-SubBG[i]+1,MAX=Y,X=Y-1;
if(X<1||Data[X]+Data[Y]<LEN)continue;
while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;
while(X<Y)
{
while(X<Y&&Data[X]+Data[Y]<LEN)X++;
for(int t=Y-1;t>=X;t--)
Val[++P]=Data[Y]+Data[t];
//Cnt+=Y-X;
Y--;
}
}
for(int i=1;i<=Sont;i++)
{
int *Data=All+SonBG[i]-1;
int Y=SonED[i]-SonBG[i]+1,MAX=Y,X=Y-1;
if(X<1||Data[X]+Data[Y]<LEN)continue;
while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;
while(X<Y)
{
while(X<Y&&Data[X]+Data[Y]<LEN)X++;
for(int t=Y-1;t>=X;t--)
Val[++P]=-(Data[Y]+Data[t]);
Y--;
}
}
sort(Val+1,Val+1+P,cmp);
int t=0,k;
for(int i=1;i<=P;i=t+1)
{
t=i,k=Val[i];
while(t<P&&(!cmp(Val[t],Val[t+1]))&&!cmp(Val[t+1],Val[t]))
k+=Val[++t];
int p=k/abs(Val[i]),o=abs(Val[i]);
for(int i=1;i<=p;i++)
printf("%d\n",o);
}
}
int main()
{
read(n),read(m);
for(int i=2;i<=n;i++)
{
int a,b,c;
read(a),read(b),read(c);
Add(a,b,c),Add(b,a,c);
}
GetSize(1,1);
SUM=n;
MX[Rt=0]=n*2;
//SonBG[Rt]=1;
GetRoot(1,1);
Div(Rt);
int L=1,R=M*2,Mid;
while(L<R)
{
Mid=L+R>>1;
Mid++;
if(Query(Mid))L=Mid;
else R=Mid-1;
}
//return 0;
COUT(L);
return 0;
}
T3:考虑数字0与1出现情况
0只能由1得出
1可以由0或1得出
压缩01的状态 发现若最终态合法则可行
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
char c;
inline void read(int&a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int a[100021],n;
bool ck()
{
int i;
while(n>1)
{
if(!a[i])a[1]=2;
if(a[n]==1)n--;
else if(a[n]==3)a[n]=2;
for(i=n;i;i--)
if(!a[i])
{
if(a[i-1]==1)
a[i-1]=2,a[i]=-1;
else if(a[i-1]==3)
a[i-1]=2,a[i]=2;
else return false;
}
int tmp=0;
for(i=1;i<=n;i++)
if(a[i]!=-1)
a[++tmp]]=a[i];
n=tmp;
for(i=1;i<=n;i++)
a[i]--;
}
return true;
}
int main()
{
int T,i,n;
for(scanf("%d",&T);T;T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
puts(ck()?"TAK":"NIE");
}
}