题解 | generator 3-2019牛客暑期多校训练营第五场D题

题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss题目描述:输入描述:输出描述:示例1:示例2:题解:代码:/*{{{*/#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>...
摘要由CSDN通过智能技术生成

题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss
题目描述:
在这里插入图片描述
输入描述:
在这里插入图片描述
输出描述:
在这里插入图片描述
示例1:
在这里插入图片描述
示例2:
在这里插入图片描述
题解:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码:

/*{{{*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#include<vector>
#include<limits.h>
#include<assert.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORS(I, S) for (int I = 0; S[I]; ++I)
#define RS(X) scanf("%s", (X))
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(LL &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }
template<class T> void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const LL &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template<class T,class U> void _W(const pair<T,U> &x) {_W(x.F); putchar(' '); _W(x.S);}
template<class T> void _W(const vector<T> &x) { for (auto i = x.begin(); i != x.end(); _W(*i++)) if (i != x.cbegin()) putchar(' '); }
void W() {}
template<class T, class... U> void W(const T &head, const U &... tail) { _W(head); putchar(sizeof...(tail) ? ' ' : '\n'); W(tail...); }
#ifdef HOME
 #define DEBUG(...) {printf("# ");printf(__VA_ARGS__);puts("");}
#else
 #define DEBUG(...)
#endif
int MOD = 1e9+7;
void ADD(LL& x,LL v){x=(x+v)%MOD;if(x<0)x+=MOD;}
/*}}}*/
const int SIZE = 2e5+10;
struct CycleSequence {
    VI d0,d;
    void extend_st(int m) {
        if(m<=SZ(d0)) return;
        int it=0;
        while(SZ(d0)<m){
            d0.PB(d[it]);
            it++;
            if(it==SZ(d))it=0;
        }
        if(it) rotate(d.begin(),d.begin()+it,d.end());
    }
    int get_tail() { return SZ(d0);}
}xs, ys;
int pos[SIZE], gen_tmp[SIZE];
void gen(int x, int a, int b, int mod, CycleSequence& cs){
    REP(i,mod)pos[i] = -1;
    LL now = x;
    int id = 0;
    while(pos[now] == -1){
        gen_tmp[id] = now;
        pos[now] = id++;
        now = (now * a + b) % mod;
    }
    REP(i, pos[now]) cs.d0.PB(gen_tmp[i]);
    REPP(i, pos[now], id) cs.d.PB(gen_tmp[i]);
}
struct Point{
    LL x,y;
    int id;
    Point(int _x=0,int _y=0):x(_x),y(_y),id(-1){}
    LL operator*(const Point& b)const{return x*b.y-y*b.x;}
    Point operator-(const Point& b)const{
        return Point(x-b.x,y-b.y);
    }
    bool operator<(const Point& b)const{return MP(x,y)<MP(b.x,b.y);}
    void scan(){
        int _x,_y;
        R(_x,_y);
        x=_x;y=_y;
    }
    PLL get_pair(){
        return MP(x,y);
    }
}concerened_points[SIZE * 3];
int pn;
bool point_cmp(Point X,Point Y){
    LL v1=X.x*Y.y,v2=X.y*Y.x;
    if (v1==v2)return abs(X.x)+abs(X.y)<abs(Y.x)+abs(Y.y);
    return v1>v2;
}
LL convex_hull_area(Point _p[],int N){
    REPP(i,1,N){
        if(_p[i].get_pair()<_p[0].get_pair()){
            swap(_p[0],_p[i]);
        }
    } 
    Point O=_p[0];
    REP(i,N){_p[i].x-=O.x;_p[i].y-=O.y;}
    sort(_p+1,_p+N,point_cmp);
    vector<Point>ret;
    ret.PB(_p[0]);
    REPP(i,1,N){
        while(SZ(ret)>1&&(ret.back()-ret[SZ(ret)-2])*(_p[i]-ret[SZ(ret)-2])<=0)ret.pop_back();
        ret.PB(_p[i]);
    }
    if(SZ(ret) <= 2) return 0;
    LL ans = ret[0] * ret[SZ(ret)-1];
    REPP(i,1,SZ(ret)) ans += ret[i] * ret[i-1];
    return abs(ans);
}
template<class T>
T rmqfunc(T a, T b) {
    return MP(max(a.F,b.F),min(a.S,b.S));
}

template <class T,T RmqFunc(T,T)>
class RMQ{
    public:
        vector<int>log2;
        vector<vector<T>> values;

        template<class IterType> void build(IterType begin, IterType end){
            assert(begin!=end);
            int n=end-begin;
            log2=vector<int>(n+1);
            for(int i=2;i<=n;i++)log2[i]=log2[i>>1]+1;
            values=vector<vector<T> >(log2.back()+1,vector<T>(n));
            for(int i=0;i<n;i++){
                values[0][i]=*(begin+i);
            }
            for(int i=1;i<=log2.back();i++){
                int len=1<<i;
                int half_len=1<<(i-1);
                for(int j=0;j+len<=n;j++){
                    values[i][j]=RmqFunc(values[i-1][j], values[i-1][j+half_len]);
                }
            }
        }
        T query(int ll,int rr) {
            int len = rr-ll+1;
            int lv=log2[len];
            return RmqFunc(values[lv][ll], values[lv][rr-(1<<lv)+1]);
        }
};

void add_points(LL n,const VI& d1,const VI& d2) {
    if(n<=0)return;
    MS1(pos);
    VPII AA;
    REP(i,SZ(d1)){
        if(pos[i]!=-1)continue;
        for(int now=i;pos[now]==-1;now=(now+SZ(d2))%SZ(d1)) {
            pos[now] = SZ(AA);
            AA.PB({d1[now],d1[now]});
        }
    }
    int seg=SZ(d1)/__gcd(SZ(d1),SZ(d2));
    RMQ<PII,rmqfunc> rmq;
    rmq.build(ALL(AA));
    REP(i,SZ(d2)){
        if(i>=n)break;
        LL tt = (n-1-i) / SZ(d2) + 1;
        int me=pos[i%SZ(d1)];
        int ll=me/seg*seg;
        int rr=ll+seg-1;
        PII ret;
        if(tt>=seg) {
            ret = rmq.query(ll,rr);
        }
        else if(me+tt-1<=rr) {
            ret = rmq.query(me,me+tt-1);
        }
        else {
            ret = rmqfunc(rmq.query(me,rr), rmq.query(ll,ll+tt-(rr-me+1)-1));
        }
        concerened_points[pn++] = Point(ret.F, d2[i]);
        concerened_points[pn++] = Point(ret.S, d2[i]);
    }
}
int main(){
    int x0, y0, a_x, a_y, b_x, b_y, mod_x, mod_y;
    LL n;
    R(x0, y0, a_x, a_y, b_x, b_y, mod_x, mod_y, n);
    gen(x0, a_x, b_x, mod_x, xs);
    gen(y0, a_y, b_y, mod_y, ys);
    int tail_len=max(xs.get_tail(), ys.get_tail());
    xs.extend_st(tail_len);
    ys.extend_st(tail_len);
    add_points(n - tail_len, xs.d, ys.d);
    REP(i,min(n, (LL)tail_len)) {
        concerened_points[pn++] = Point(xs.d0[i],ys.d0[i]);
    }
    W(convex_hull_area(concerened_points, pn));
    return 0;
}

更多问题,更详细题解可关注牛客竞赛区,一个刷题、比赛、分享的社区。
传送门:https://ac.nowcoder.com/acm/contest/discuss

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值