T神的场。
C2 :https://codeforces.com/contest/1237/problem/C2
题目大意: n个点,每次去掉一对点,保证围成的区域不能包含其他的点,输出方案。
题目思路:
其实并没有想到C1的n方做法,直接做的C2,先按照x再按照y再按照z排序,如果两个点重合了,一定要先拿掉这些,如果两个点在一条纵轴线上,要优先拿这些,拿完之后,如果在一个面上,要优先拿这些,然后剩下的从后往前拿就行了。
#include
#define ll long long
using namespace std;
const int MAXN = 1e5+5;
struct node
{
int x,y,z,id;
}a[MAXN];
bool cmp(node a,node b)
{
if(a.x == b.x){
if(a.y == b.y){
return a.zv,v1,v2;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].x>>a[i].y>>a[i].z;
a[i].id = i;
}
sort(a+1,a+1+n,cmp);
a[0].x = 999999,a[0].y = -1;
for(int i=n;i>=1;i--){
if(a[i].x == a[i-1].x && a[i].y == a[i-1].y && a[i].z == a[i-1].z){
cout<=0;i--){
if(i!=0 && v[i].x == v[i-1].x && v[i].y == v[i-1].y){
cout<=0;i--){
if(i!=0 && v1[i].x == v1[i-1].x){
cout<=0;i-=2){
cout<
D:
https://codeforces.com/contest/1237/problem/D
题目大意:
n个数字,一个音乐演奏开始的话,直到后边碰到一个比当前碰到最大值小一半的数字会停止,问以每一个开始的话,哪个停止。
题目思路:
每一个都往后找一个第一个比他大的,在找一个第一个比他小一半的,如果先碰到比他大的,那么就可以从那个值转移过来,如果先碰到小的那个,就断了。
可以线段树上维护一个区间最小值,二分以下得到后者,用单调栈得到前者。
#include
#define ll long long
using namespace std;
const int MAXN = 1e5+5;
int a[2*MAXN];
int Min[8*2*MAXN],n;
void build(int p,int l,int r)
{
if(l==r){
Min[p] = a[l];
return ;
}
int mid = (l+r)/2;
build(2*p,l,mid);
build(2*p+1,mid+1,r);
Min[p] = min(Min[2*p],Min[2*p+1]);
}
int ask(int p,int l,int r,int L,int R)
{
if(L<=l&&r<=R){
return Min[p];
}
int mid = (l+r)/2;
int Minn = 0x7fffffff;
if(L<=mid) Minn = min(Minn,ask(2*p,l,mid,L,R));
if(R>mid) Minn = min(Minn,ask(2*p+1,mid+1,r,L,R));
return Minn;
}
int r[2*MAXN],ss[2*MAXN];
struct node
{
int id,val;
} b[2*MAXN],st[2*MAXN];
bool cmp(node a,node b)
{
return a.val > b.val;
}
bool check(int x,int idx,int cc)
{
if(ask(1,1,2*n,idx+1,idx+x) <= cc){
return 1;
}
else return 0;
}
int ans[2*MAXN];
int ma,mi;
int main()
{
cin>>n;
mi = 0x7fffffff;
for(int i=1;i<=n;i++){
cin>>a[i];
ma = max(ma,a[i]);
mi = min(mi,a[i]);
b[i].id = i;
a[n+i] = a[i];
b[i].val = a[i];
b[n+i].val = a[i];
b[n+i].id = n+i;
}
b[2*n+1].id = 2*n+1;
b[2*n+1].val = 0x7fffffff;
//cout<= 1 && b[i].val>st[tot].val){
r[st[tot].id] = i;
tot--;
}
st[++tot] = b[i];
}
sort(b+1,b+1+n,cmp);
for(int i=1;i<=n;i++){
int idx = b[i].id;
int now = (a[idx]-1)/2;
int _l = 1,_r = n-1,anss = -1;
while(_l<=_r){
int mid = (_l+_r)/2;
if(check(mid,idx,now)){
_r = mid-1;
anss = mid;
}
else{
_l = mid+1;
}
}
if(anss == -1){
ss[idx] = 0x7fffffff;
}
else ss[idx] = idx+anss;
}
for(int i=1;i<=n;i++){
int idx = b[i].id;
int big = r[idx],sm = ss[idx];
if(big < sm){
ans[idx] = ans[big] + big - idx;
ans[n+idx] = ans[idx];
}
else{
ans[idx] = sm-idx;
ans[idx+n] = ans[idx];
}
// cout<