已补(2/9)
A
题意
每天可以加一个水位标记,标记可以重合,并且告诉你每天在当前水位上有多少个标记,求每天水位下标记总和。
题解
先求出每天至少多少个,取前缀最值。
但是这样是最少的情况,而且不一定合法,因为每天最多一个。
所以倒过来取
得到每天个数之后,
就是当天水位下个数
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define RFOR(i,a,b) for(int i=a;i>=b;i--)
#define sf(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 600000+500;
const ll mod = 1e9+7;
int n;
int A[maxn],B[maxn];
int main(){
cin>>n;
int t=0;
FOR(i,1,n)sf(A[i]);
FOR(i,1,n)B[i]=max(B[i-1],A[i]+1);
//FOR(i,1,n)cout<<B[i]<<endl;
RFOR(i,n,1)B[i]=max(B[i+1]-1,B[i]);
//FOR(i,1,n)cout<<B[i]<<endl;
ll ans=0;
FOR(i,1,n){
ans+=B[i]-1-A[i];
}
cout<<ans<<endl;
}
B
题意
告诉你风速范围,告诉你 个飞机方向和速度,求满足存在某个风速能使得两个飞机同时到达 的个数,保证都是往 飞,速度和位置都带有方向。
题解
因为保证了
,所以分母不会变到
。
也就是函数是连续的,求存在
,使得
充分条件是,
单调性不易看出。
但是对于
就是一次函数,显然是单调的。
对于每个飞机计算,
和
,设为
则求满足
的对数。
简单的二维偏序,但是要考虑一下等号,因为对
排序,相等的时候我们要算上相等部分的所有。所以干脆对
倒序排,这样保证了之前的
,并且相等的时候
,这样就不会少算了
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define RFOR(i,a,b) for(int i=a;i>=b;i--)
#define sf(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 600000+500;
const ll mod = 1e9+7;
struct node{
int a,b;
friend bool operator < (node x,node y){
if(x.a==y.a)return x.b>y.b;
return x.a<y.a;
}
}A[100050];
int n,m;
double a[100050],b[100050];
vector<pair<double,int> >G;
int C[200050];
const int limit=200005;
int lowbit(int x){return (x&(-x));}
void change(int x,int d){for(int i=x;i<=limit;i+=lowbit(i)){C[i]+=(ll)d;}}
ll query(int x){if(x==0)return 0;ll ret=0;for(int i=x;i;i-=lowbit(i)){ret+=C[i];}return ret;}
int main(){
int n,w;
cin>>n>>w;
FOR(i,1,n){
int x,v;double tmp;sf(x);sf(v);
a[i]=double(v-w)/(-x);
b[i]=double(v+w)/(-x);
G.push_back(make_pair(a[i],2*i-1));
G.push_back(make_pair(b[i],2*i));
}
sort(G.begin(),G.end());
int num=1;
if(G[0].second%2)A[(G[0].second+1)/2].a=num;
else A[G[0].second/2].b=num;
for(int i=1;i<G.size();i++){
if(G[i].first>G[i-1].first)++num;
if(G[i].second%2)A[(G[i].second+1)/2].a=num;
else A[G[i].second/2].b=num;
}
ll ans=0;
memset(C,0,sizeof(C));
sort(A+1,A+1+n);
int now=0;
for(int i=1;i<=n;i++){
ans+=query(limit)-query(A[i].b-1);
change(A[i].b,1);
//cout<<A[i].b-1<<" "<<ans<<endl;
}
cout<<ans<<endl;
}