ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【补】2022.7.22———多校联测【2022年多校冲刺NOIP联训测试4】

2022-07-26 12:33:41  阅读:153  来源: 互联网

标签:cout NOIP SQ 多校 abs 联训 joke3579 include define


$Write In Front$

感觉多校联测的题比较水?

成绩综述

$112 / 174$,我菜菜

 

T1 甲国的军队

 

大水题,先打表找个规律

然后sort一下,按照B[i]与A[i]的差值降序,然后模拟

T1


#include <iostream>
#include <iomanip>
#include <algorithm>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define _MARK "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ " "
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define CASE 12
#define N 100005
#define MAXNUM 1000000002
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false);cin.tie(NULL), cout.tie(NULL);}
long long T, n, final_ans, now;
struct node{
    long long die, need, derta;
}a[N];
inline bool comp(node A, node B){
    if(A.derta != B.derta) return A.derta > B.derta;
    else if(A.die != B.die) return A.die > B.die;// 这应该没影响
    else return A.need > B.need;
}
inline void Clean(){now = final_ans = 0;}
inline void work(){
    Clean();
    // T1 额
    // 这个就是derta是吗
    // die <= need
    cin >> n;
    for(re i = 1 ; i <= n ; ++ i){
        cin >> a[i].die >> a[i].need;
        a[i].derta = a[i].need-a[i].die;
    }
    sort(a+1, a+n+1, comp);
    for(re i = 1 ; i <= n ; ++ i){
        if(now >= a[i].need){
            now -= a[i].die;
            continue;
        }
        final_ans += (a[i].need-now), now = a[i].need;
        now -= a[i].die;
    }
    cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    cin >> T;
    while(T --){
        work();
    }
    return GMY;
}

 

T2 虚弱

二分。具体看Chen_jr的博客

提示:二分可以“随机化”

但是NIMA像这种6位数精度的就算了吧

然后还有技巧,clock()大法

我这个程序常数大,所以用clock()提前终止二分,本来60然后就A掉了

T2
 

#include <iostream>
#include <iomanip>
#include <cmath>
#include <random>
#include <ctime>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define _MARK "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ " "
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define eps 0.000000000001
#define N 200005
#define MAXNUM 10005
#define mod %
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false);cin.tie(NULL), cout.tie(NULL);}
int n, ner;
long long tim;
double final_ans(11451419.0);
double a[N], kl[N];
inline bool check(double number){
    for (re i = 1 ; i <= n ; ++ i)
        kl[i] = a[i] + number;// 注意是加 因为有负数
    double mn(kl[1]), mx(kl[1]), now_min(0), now_max(0);
    for (re i = 1 ; i <= n ; ++ i){
        now_min += kl[i], now_max += kl[i];
        mn = MIN(mn, now_min), mx = MAX(mx, now_max);
        if (now_min > 0) 
            now_min = 0;// 前面的不要了开另一个区间,因为前面的加起来已经大于0,后面咋变小都没有重新开一个区间、now_min=0更优,所以重新开一个区间
        if (now_max < 0) 
            now_max = 0;
    }
    double harmony = MAX(abs(mn), abs(mx));
    if (harmony < final_ans) final_ans = harmony;
    if (mx < 0) return false;
    // mx >= 0 了
    if (mn > 0) return true;// 最小的都大于0,那么根本不够小,应该减得更小
    // mn <= 0 了
    if (abs(mn) < abs(mx)) return true;// 应该更小一些以使得abs(mn)更大,也就是x更大
    // abs(mn) >= abs(mx);
    return false;
}
inline void work(){
    random_device rd;// 来吧!随机化!!!
    mt19937 myrand(rd());
    // 既然虎哥都说惹。。那么我就先改题吧
    // 模拟退火先放一下)
    // T2
    // sum为前缀和数组,那么题意:
    // 找到一个最小的ans,使得任意的1 <= j <= i <= n, sum[i]-sum[j] - (i-j)*x <= ans
    // 所以拆开
    // sum[i]-i*x - (sum[j]-j*x) <= ans
    // 所以要找的ans:
    // ans = MAX{sum[i]-i*x} - MIN(sum[j]-j*x)
    // 注意到      ↑                   ↑   各是关于x的两个一次函数
    // 这本来是一个单谷函数,可以用爬山算法,模拟退火额也行
    // 然而可以三分。但是蒟蒻不会三分
    // 所以考虑二分(考虑陈钩R(划掉))
    // 考虑两个极值(最初时)。一个是最大的记为mxx,一个是最小的记为mnn
    // 两种情况。
    // Case 1: mxx > 0 && mnn > 0
    // 这种情况下我们会希望让mnn一直减小到0之后接着减小,同时mxx当然也会减小,但是abs()是个单谷的,所以过了0这个界限之后abs(mnn)有朝一日会再减一点点点就会比比 abs(mxx)大,这里就是我们想要的谷点
    // 所以二分减去多少x, 找到那个谷点
    // 这种情况启示我们二分的时候要边界应该包括正数
    // Case 2: mxx > 0 && mnn < 0
    // 这种情况下也是,和上面差不多,这个可以再分成两种情况,即 ↓
    // 这种情况启示我们二分的时候边界应该包括负数。因为初始时可能abs(mnn) > abs(mxx),也可能【 < 】。【 > 】 的话就肯定是要让mnn增加也就是让abs(mnn)减小,让abs(mxx)增大,然后看拐点
    // 然后剩下的就是代码实现了 代码实现还是比较ex的。。。(对于本蒟蒻而言)
    // 那个“y”图像,一个是mx,一个是abs(mn)
    cout.setf(ios::fixed), cout.precision(6);
    cin >> n; ner = (sqrt(sqrt(n))+1) * 100000;
    for (re i = 1 ; i <= n ; ++ i)
        cin >> a[i];
    double l = -10000.0, r= 10000.0, mid;
    // int times(0);
    // long long tim = clock();
    // while (r-l >= eps) {
    //     mid = ((l + r) / 2.0) + (SQ(SQ(SQ(SQ(SQ(SQ(SQ(SQ((double)myrand())))))))));// -x, 过去后是+x
    //     mid -= SQ(SQ(SQ(SQ(SQ(SQ(SQ(SQ((double)myrand()))))))));
    //     cout << l << _ << mid << _ << r << '\n';
    //     if(check(mid) == true) r = mid;// 值应当更小,x应当更大
    //     else l = mid;
    //     times ++;
    //     if(times == 50000) break;
    // }
    
    while (r-l >= eps) {
        // mid = ((l + r) / 2.0) + myrand()*1e-9;// -x, 过去后是+x
        // mid -= myrand()*1e-8;
        // cout << l << _ << mid << _ << r << '\n';
        mid = ((l + r) / 2.0);
        if(check(mid) == true) r = mid;// 值应当更小,x应当更大
        else l = mid;
        // times ++;
        // if(times == 1000) break;
        if((double)(clock()-tim) * 1000 / CLOCKS_PER_SEC >= 2995) break;
    }
    // cout << clock() - tim << endl;
    cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
    tim = clock();
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

 

T3 萨鲁曼的半兽人

joke3579的SPFA

我把我俩的聊天记录粘在这里

mad,luog什么复制规则,从下往上是时间顺序,倒着看吧。。


I: 懂
I: joke3579:终点自然就是n字符的右侧
joke3579:?因为你在字符间建点
I:还是您的SPFA
I: 为啥输出的是dis[n+1]?
I: ```printf("%lld\n",dis[n+1]-1);``` 07-24 21:35
I: joke
I: 谢谢
I: 泄泄
I: 泄泄joke
I: ylrc
joke3579:也不长 就当kmp了
joke3579:对的
I: joke,您用了马拉车?
I: joke 有什么处理回文子串的好方法么
joke3579:?manacher可以在O(n)的复杂度内找出所有极长回文子串
I: 然而处理子回文串不是n^3的吗
I: 好像真是
I: 唔
joke3579:为啥是最短路? -> 因为你要挑出最少的字符串
joke3579:i和i-1为啥要建? -> 因为如果你一直往前莽 总会有向前走不了的时候
I: i和i-1为啥要建?
I: 为啥是最短路?
joke3579:就在起始字符左边和终止字符右边建
I: others?
joke3579:因为有长度为1的回文串,你自己向自己建边显然fake
I: 蒟蒻比较菜,谢谢大佬耐心gg
I: 为啥让【】与【】建?
joke3579:?什么叫物理意义
I: 巨,不过根本没看出建边的物理意义啊?
I: 巨,大佬的每一言每一语都重如千钧,像我这样的蒟蒻是无法短时间内看懂的,谢谢大佬!
joke3579:这是我给jjdw发的讲解
joke3579:拿T3当例题 首先我们有一个f[]数组,记f[i]为以i位置的字符为左端点向右延申极长回文串对应的右端点 然后考虑在字符间建边 因为有长度为1的回文串,你自己向自己建边显然fake 然后从i向f[i]+1建一条长度为1的边,保证了如果区间连续的话最短路就是正确结果 我们发现如果一直莽根本找不到正确结果 怎么办呢?考虑反悔 向i到i-1建一条长度为0的边
joke3579:因为这是道最小覆盖问题
I: 昨天的T3,为什么能用SPFA啊? 07-24 20:05 I: 还在吗joke
T3
 

#include <iostream>
#include <iomanip>
#include <queue>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define _MARK "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ " "
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 100005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false);cin.tie(NULL), cout.tie(NULL);}
int n, R, mid, star_cnt;
char sr[N];
bool inq[N];// inside_queue
int p[N<<1], f[N], dis[N], head[N];
struct star{
    int v, w, nxt;
}e[N<<1];
queue<int> q;
string a;
// T3 萨鲁曼的半兽人
// joke的SPFA,真的diao
// 所以用joke 的SPFA来了
inline void star_add(int u, int v, int w){e[++ star_cnt].v=v, e[star_cnt].w=w, e[star_cnt].nxt=head[u], head[u]=star_cnt;}
inline void Clean(){
    star_cnt = mid = R = 0; a.clear();
    for (re i = 1 ; i <= n+3 ; ++ i)
        sr[i] = head[i] = f[i] = p[i] = inq[i] = 0, dis[i] = 1145141919;
}
inline void spfa(int x){
    q.push(x), dis[x] = 0, inq[x] = true;
    while (q.empty() == false){
        x = q.front(), q.pop();// 一x多用(doge)
        inq[x] = false;
        for (re i = head[x] ; i ; i = e[i].nxt){
            if (dis[e[i].v] > dis[x]+e[i].w){
                dis[e[i].v] = dis[x]+e[i].w;
                if (inq[e[i].v] == false)
                    q.push(e[i].v), inq[e[i].v]=true;
            }
        }
    }
}
inline void work(){
    a += '(';
    for (re i = 1 ; i <= n ; ++ i)
        a += '#', a += sr[i];
    a += '#', a+= ')';
    for (re i = 1 ; i <= a.size()-2 ; ++ i){
        p[i] = ( (R > i) ? (MIN(p[(mid<<1)-i], R-i)) : (1));
        while(a[i+p[i]] == a[i-p[i]]) p[i] ++;
        if (i+p[i] > R)
            R = i+p[i], mid = i;
    }
    for (re i = 1 ; i <= a.size()-2 ; ++ i){
        if ( ((i-1) & 1) == 1 )
            f[(i>>1) - (p[i]>>1) + 1] = MAX(f[(i>>1) - (p[i]>>1) + 1], (i>>1) + (p[i]>>1) - 1);
        else if (p[i] > 1)
            f[((i-1)>>1) - ((p[i]-1)>>1) + 1] = MAX(f[(i-1)>>1 - ((p[i]-1)>>1) + 1], ((i+1)>>1) + ((p[i]-1)>>1) - 1);
    }
    star_add(1, f[1]+1, 1);
    for (re i = 2 ; i <= n ; ++ i)
        star_add(i, f[i]+1, 1), star_add(i, i-1, 0);// joke\
                                    “一直往前莽可能到不了”
    spfa(1);
    // MARK;
    cout << dis[n+1]-1 << '\n';//\
           字符之间建边,点会多一个(手模) 减一很简单,他问的是“连接”,表明过了dis[n+1]个边dis[n+1]+1个点,其中每两个点是一个“子回文串”so有dis[n+1]个,把他们连接起来要有dis[n+1]-1
}
/*
obocodo
abcdef
abcdcba
*/
// #define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(a);
    #endif
    Fastio_setup();
    for (re i = 1 ; i <= 100000 ; ++ i) dis[i] = 1145141919;
    while (true){
        Clean();
        cin >> sr+1; n = strlen(sr+1);
        // cout << n << _ << strlen(sr+1) << '\n';
        if(n == 0) break;
        work();
    }
    return GMY;
}

 

T4 序列

先吃饭去

a

a

a

标签:cout,NOIP,SQ,多校,abs,联训,joke3579,include,define
来源: https://www.cnblogs.com/charphi/p/16520506.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有