#include
#include
#include
#include
#define ll long long
using namespace std;
int read()
{
int k=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) k=k*10+c-'0';return k*f;
}
const int N=100055;
int n,m,a[N],b[N],c[N];
int sum[N<<2],la[N<<2];
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
void pu(int k)
{
sum[k]=sum[k<<1]+sum[k<<1|1];
}
void pd(int k,int l,int r)
{
if(!la[k])
{
la[k<<1]=la[k<<1|1]=sum[k<<1]=sum[k<<1|1]=0;
la[k]=-1;
}
else if(la[k]==1)
{
la[k<<1]=la[k<<1|1]=1;
la[k]=-1;
int mid=l+r>>1;
sum[k<<1]=mid-l+1;
sum[k<<1|1]=r-mid;
}
}
void build(int k,int l,int r,int x)
{
la[k]=-1;
if(l==r) {sum[k]=(a[l]>=x);return;}
int mid=l+r>>1;
build(lson,x);build(rson,x);
pu(k);
}
void ch(int k,int l,int r,int a,int b,int v)
{
if(a>b) return;
if(a<=l&&b>=r)
{
if(v==0) sum[k]=la[k]=0;
else sum[k]=r-l+1,la[k]=1;
return;
}
int mid=l+r>>1;pd(k,l,r);
if(a<=mid) ch(lson,a,b,v);
if(b>mid) ch(rson,a,b,v);
pu(k);
}
int query(int k,int l,int r,int a,int b)
{
if(a<=l&&b>=r) return sum[k];
int mid=l+r>>1,res=0;pd(k,l,r);
if(a<=mid) res=query(lson,a,b);
if(b>mid) res+=query(rson,a,b);
return res;
}
int chk(int x)
{
build(1,1,n,x);
for(int i=1;i<=m;i++)
{
if(b[i]c[i])
{
int s=query(1,1,n,c[i],b[i]);
ch(1,1,n,c[i],c[i]+s-1,1);
ch(1,1,n,c[i]+s,b[i],0);
}
}
// cout<=l)
{
mid=l+r>>1;
if(chk(mid)) res=mid,l=mid+1;
else r=mid-1;
}
cout<
#include
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair PII;
#define X first
#define Y second
inline int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int maxn=2010;
const double eps=1e-6;
int n,X1,Y1,X2,Y2,ans;
bool have[maxn][maxn];
double f(double x)
{
return (double)((Y2-Y1)*x+X2*Y1-X1*Y2)/(double)(X2-X1);
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
X1=read();Y1=read();X2=read();Y2=read();
if(X1==X2)continue;
if(Y1==Y2)continue;
if(X1>X2)swap(X1,X2),swap(Y1,Y2);
for(int x=X1;xf2)swap(f1,f2);
if(fabs(f1-ceil(f1))
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define int long long
using namespace std;
int read()
{
int k=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) k=k*10+c-'0';return k*f;
}
const int N=100055,inf=1ll<<50;
int n,m,a[N],b[N],c[N],v[N],f[N];
int s[N],s2[N];
int mn[N<<2];
bool cmp(int x,int y)
{
return a[x]>1;
build(lson);build(rson);
pu(k);
}
void ch(int k,int l,int r,int a,int b)
{
if(l==r) {mn[k]=b;return;}
int mid=l+r>>1;
if(a<=mid) ch(lson,a,b);
else ch(rson,a,b);
pu(k);
}
int query(int k,int l,int r,int a,int b)
{
if(a<=l&&b>=r) return mn[k];
int mid=l+r>>1,res=inf;
if(a<=mid) res=query(lson,a,b);
if(b>mid) res=min(res,query(rson,a,b));
pu(k);
return res;
}
void solve(int l,int r)
{
if(l==r) return;
int mid=l+r>>1,tp=0,tp2=0,l1=mid-l+1,l2=r-mid;
solve(l,mid);
for(int i=1;i<=l1;i++)
b[i]=l+i-1;
for(int i=1;i<=l2;i++)
c[i]=mid+i;
sort(b+1,b+1+l1,cmp);sort(c+1,c+1+l2,cmp);
int now=1;
for(int i=1;i<=l2;i++)
{
while(now<=l1&&a[b[now]]c[i]) tp2--;
int pos=0;
if(tp2) pos=a[s2[tp2]]+1;
f[c[i]]=min(f[c[i]],v[c[i]]+query(1,0,n,pos,a[c[i]]));
s2[++tp2]=c[i];
}
for(int i=1;i<=l1;i++)
ch(1,0,n,a[b[i]],inf);
solve(mid+1,r);
}
main()
{
n=read()+1;a[n]=n;
for(int i=1;i<=n;i++)
f[i]=inf;
for(int i=1;i
===== G. Dreamoon and NightMarket =====
=== 题意 ===
给了 $n$ 个有价值的物品,求价值第 $k$ 小的集合.
=== 题解 ===
我们用优先队列存已有的集合,每次我们取出最小的集合,设该集合价值和为 $v$ ,最大价值的物品为 $a_i$ ,我们就加入 $v-a_i+a_{i+1}$ 和 $v+a_{i+1}$ ,可以保证队列里面的集合一定有最小的.
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
int read()
{
int k=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) k=k*10+c-'0';return k*f;
}
const int N=200055;
int n,m,a[N];
typedef pair P;
priority_queue, greater
> q;
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
a[i]=read();
sort(a+1,a+1+n);
q.push(P(a[1],1));
for(int i=1;i
===== F. Lonely Dreamoon 2 =====
=== 题意 ===
调整一个序列的顺序,使得$min\{|a_i-a_{i-1}|\}$最大。
=== 题解 ===
分奇偶讨论,偶数是$a_i$和$a_{i+\frac{n}{2}}$相邻,奇数就找一个$|a_i-a_{i+\frac{n}{2}}|$最小的位置拿出来。
===== H. Split Game =====
=== 题意 ===
给一个多边形,全在第一象限,有一条过原点的直线,问最多能把这个多边形划分成多少区域
=== 题解 ===
先考虑给定一条分界线怎么数区域,我的做法是先算出所有交点然后看这条线两侧有多少个山峰,便是多少个区域,我们便可以从这个思路继续拓展,继续想直线在旋转的过程中答案的增量,十分善良的是数据已经是按照逆时针转好的,注意讨论这个点前驱后继组成的形状。
#include
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair PII;
#define X first
#define Y second
inline int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int maxn=100010;
struct Point{
LL x,y;
Point() {}
Point(double _1,double _2):x(_1),y(_2) {}
Point operator - (const Point&s) const {return Point(x-s.x,y-s.y);}
LL operator * (const Point&s) const {return x*s.y-y*s.x;}
LL len() {return x*x+y*y;}
}a[maxn];
int n,N,ans,now_ans,R[maxn];
bool del[maxn];
bool cmp(int xx,int yy)
{
return (double)a[xx].y/(double)a[xx].x<(double)a[yy].y/(double)a[yy].x;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i].x,&a[i].y);
a[0]=a[n];a[n+1]=a[1];
for(int i=1;i<=n;i++)if((a[i]-a[i+1])*(a[i]-a[i-1])==0)del[i]=1;
for(int i=1;i<=n;i++)if(!del[i])a[++N]=a[i];
a[0]=a[n];a[N+1]=a[1];
n=N;
for(int i=1;i<=n;i++)R[i]=i;
sort(R+1,R+N+1,cmp);
int i=1;
while(i<=n)
{
int tmp=0,j;
for(j=i;j<=n && a[R[i]]*a[R[j]]==0;j++)
{
int pos=R[j];
if(a[pos]*a[pos-1]>=0 && a[pos]*a[pos+1]>0)
{
if((a[pos-1]-a[pos])*(a[pos+1]-a[pos])>0)now_ans++;
else tmp++;
}
if(a[pos]*a[pos-1]<0 && a[pos]*a[pos+1]<=0)
{
if((a[pos-1]-a[pos])*(a[pos+1]-a[pos])<0)now_ans--;
else tmp--;
}
}
if(tmp>0)ans=max(ans,now_ans+tmp);
else ans=max(ans,now_ans);
now_ans+=tmp;
i=j;
}
printf("%d\n",ans+1);
return 0;
}
===== J. Zero Game =====
=== 题意 ===
有一个$01$串,允许进行至多$K$次操作,每次移动一个数的位置,问能构造出最长的连续$0$的长度
=== 题解 ===
把原串中连续$0$和$1$统计一下长度,那么序列就变成了一个$0$和$1$交错的序列,我们无视开头的$1$,每一串$0$和下一串$1$视作放在一个位置,那么记$A[i]$为$0$的前缀和$B[i]$为$1$的前缀和,设$f[i]$为$i$位置的$0$串结尾的最长长度
那么对于给定的$K$有以下转移方程:
$f[i]=max\{A[i]-A[j]+K-(B[i-1]-B[j])\}$
用单调队列转移即可
复杂度$O(NQ)$
#include
#include
#include
#include
#include
#include
#include
#include
#include
===== 训练实况 =====
开局 fyh看**E** hxm看**A** wxg中途加入看到**G**有人过就看**G**
wxg想出**G**开写**G**
0:35 wxg过**G**,fyh看**C** 和hxm讨论出**C**做法开写**C**
0:56 fyh过**C**,wxg想出**A**,开写**A**
1:24 wxg过**A** fyh看**H**,**J** 成功给hxm翻译错题,hxm想出错题做法,开写**J**
1:40 hxm没过**J**,重新读题,发现读错题,之后重新想**J**,wxg想**E** fyh想**I**和**H**
2:56hxm过**J**,推出**D**,讨论出做法后开写**D**并调,fyh写**H**并调
4:24 hxm过**D**,wxg想出**E**,开写**E**
4:58 wxg绝杀**E** fyh没过**H**
===== 训练总结 =====
wxg: 罚时永远的痛
hxm:这一场发挥不错,但在罚时方面还需改进。
fyh:被一道不卡精度的题愣是生生卡到了精度,以后再也不用atan2进行极角排序了呜呜呜