DAY 6

T4://还是能开大一点数组就尽量开一点

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 5e6 + 20;
struct node {
    double l, r;
} a[maxn];
int n, m, r;
double deg, c, d;
const double pi = acos(-1), eps = 1e-10;
double p[maxn << 1];
int main() {
    freopen("sight.in", "r", stdin);
    freopen("sight.out", "w", stdout);
    scanf("%d%d", &n, &r);
    for (int i = 1; i <= n; i++) {
        ll x, y;
        scanf("%lld%lld", &x, &y);
        d = sqrt(x * x + y * y);
        deg = atan2(y, x);
        c = acos(r / d);
        a[i].l = deg + c, a[i].r = deg - c;  //此时的顺序是顺时针的
        if (a[i].l - pi > 0)
            a[i].l -= 2 * pi;
        if (a[i].r + pi < 0)
            a[i].r += 2 * pi;
        if (a[i].l <= a[i].r && (fabs(a[i].r - a[i].l - pi) <= eps || a[i].r - a[i].l - pi > 0))
            swap(a[i].l, a[i].r);
        if (a[i].l >= a[i].r && (fabs(a[i].l - a[i].r - pi) <= eps || a[i].l - a[i].r - pi < 0))
            swap(a[i].l, a[i].r);  //
        //因为lower——bould计数实际上实在顺时针方向上计数,所以当初存弧度的时候也要计数,但是转化成直角坐标系的时候两者反而是互补的
        p[++m] = a[i].l;
        p[++m] = a[i].r;
    }
    // printf("%d\n",m);
    sort(p + 1, p + 1 + m);
    //    for(int i=1;i<=m;i++) printf("%lf ",p[i]);
    long long ans = 0;

    for (int i = 1; i <= n; i++) {
        ll L, R;
        L = lower_bound(p + 1, p + 1 + m, a[i].l) - p;
        R = lower_bound(p + 1, p + 1 + m, a[i].r) - p;
        //        swap(L,R);
        // printf("%lld %lld\n",L,R);
        if (L <= R)
            ans += R - L - 1;
        else
            ans += m + R - L - 1;
    }
    printf("%lld", ans >> 1);
    return 0;
}
View Code

 T3:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define ll long long
using namespace std;
const ll N=5e5+10;
struct node{
    ll to,next,w;
}a[N*12];
ll n,m,p[N],k[N],b[N],sumk,sumb;
ll l,r,maxs,mins,tot,ls[N];
bool v[N],vis[N];
ll read() {
    ll x=0,f=1; char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
}
void addl(ll x,ll y,ll w){
    a[++tot].to=y;
    a[tot].next=ls[x];
    ls[x]=tot;a[tot].w=w;
    return;
}
ll check(ll K,ll B,ll x){
    if((K-k[x])==0){
        if(b[x]-B)return 0;
        return 1;
    }
    if((b[x]-B)%(K-k[x])!=0)return 0;
    ll w=(b[x]-B)/(K-k[x]);
    if(l>w||w>r)return 0;
    l=w;r=w;return 1;
}
bool dfs(ll x){
    v[x]=1;
    sumk+=k[x];
    sumb+=b[x];
    if(k[x]==1){
        l=max(l,-b[x]);
        r=min(r,p[x]-b[x]);
        if(l>r)return 0;
    }
    else{
        l=max(l,b[x]-p[x]);
        r=min(r,b[x]);
        if(l>r)return 0;
    }
    for(ll i=ls[x];i;i=a[i].next){
        ll y=a[i].to;
        if(v[y]){
            if(!check(-k[x],a[i].w-b[x],y))return 0;
        }
        else{
            k[y]=-k[x];
            b[y]=a[i].w-b[x];
            if(!dfs(y))return 0;
        }
    }
    return 1; 
}
int main()
{
//    freopen("diamond.in","r",stdin);
//    freopen("diamond.out","w",stdout);
    n=read();m=read();ll sum=0;
    for(ll i=1;i<=n;i++)
        sum+=(p[i]=read());
    for(ll i=1;i<=m;i++){
        ll x=read(),y=read(),w=read();
        addl(x,y,w);addl(y,x,w);
    }
    for(ll i=1;i<=n;i++){
        if(v[i])continue;
        l=sumk=sumb=0;r=p[i];k[i]=1; 
        if(!dfs(i))return printf("NIE\n")&0;
        else{
            if(sumk<0)maxs+=l*sumk+sumb,mins+=r*sumk+sumb;
            else maxs+=r*sumk+sumb,mins+=l*sumk+sumb;
        }
    }
    printf("%lld %lld\n",sum-maxs,sum-mins);
}

 

posted @ 2020-12-04 08:19  ILH  阅读(92)  评论(0)    收藏  举报