【2019.10.25】

summary

  • 分情况拿分保底真的很好用 像我这种辣鸡应该注意保底
  • 打题不要慌 有条理 不要东一条西一条

小奇采药

对于 30% 的数据,O(2n ) 枚举取 or 不取

对于 60% 的数据,O(nm) 做 01 背包,即 f(i, j) 表示前 i 株 草药,耗费 j 的时间能达到的最?代价。

对于 100% 的数据,注意到 m,t,v 纯随机

那么不会选太多的草药,?耗时较少的草药有很?概率存在 于最优解中

针对这些性质优化搜索

当然也可以合理使用随机化和卡时,复杂度 O(?学)

最基础60昏的背包

dfs写错了... 幸好我分开搞得 不然就爆炸

struct node{int co,val;}a[N];
bool cmp(node x,node y){return x.co>y.co;}

ll f[100010],ans,sumc[N],sumv[N];
void work(){//60昏
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;++i)
    for(int j=m;j>=a[i].co;--j)
    f[j]=max(f[j],f[j-a[i].co]+a[i].val);
    printf("%lld\n",f[m]);
}

bool vis[N];
void dfs(int pos,ll co,ll val){
    ans=Max(ans,val);
    if(pos>n) return;
    if(co+a[n].co>m) return;
    if(val+sumv[pos]<=ans) return;
    if(co+sumc[pos]<=m){ans=Max(val+sumv[pos],ans);return;}
    if(co+a[pos].co<=m) dfs(pos+1,co+a[pos].co,val+a[pos].val);
    dfs(pos+1,co,val);
}
void work2(){
    ans=0;dfs(1,0,0);
    printf("%lld\n",ans);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int T;rd(T);
    while(T--){
        rd(n),rd(m),sumv[n+1]=sumc[n+1]=0;
        for(int i=1;i<=n;++i) rd(a[i].co),rd(a[i].val);
        sort(a+1,a+n+1,cmp);
        for(int i=n;i;--i) sumv[i]=sumv[i+1]+a[i].val,sumc[i]=sumc[i+1]+a[i].co;
        //if(m<=100000) work();
        work2();
    }
    return 0;
}

小奇的数列2

第一反应 双指针?!

很容易发现 若一个区间为可约的 那么这个区间的gcd一定等于其最小值

然后发现可以二分 就开始打线段树来维护 打完后发现二分的过程中有很多此询问 gcd和最小值都可以用st表来维护 然后\(O(1)\)询问最合适了!

然后这就是正解辽?!

int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int gc,mn;
void query(int x,int y){
    int s=lg[y-x+1];
    gc=gcd(Gc[x][s],Gc[y-(1<<s)+1][s]),mn=Min(Mn[x][s],Mn[y-(1<<s)+1][s]);
}
bool check(int mid){
    for(int l=1;l+mid<=n;++l)
    if(query(l,l+mid),gc==mn) return 1;
    return 0;
}
int main(){
    //freopen("sequence.in","r",stdin);
//  freopen("sequence.out","w",stdout);
    rd(n);
    for(int i=1;i<=n;++i) rd(a[i]);
    cm[0]=1,lg[0]=-1;for(int i=1;i<20;++i) cm[i]=cm[i-1]<<1;
    for(int i=1;i<=n;++i) Gc[i][0]=Mn[i][0]=a[i],lg[i]=lg[i>>1]+1;Mn[n+1][0]=0;
    for(int j=1;j<20;++j)
        for(int i=1;i+cm[j]-1<=n+1;++i){
            Gc[i][j]=((Gc[i][j-1]==1||Gc[i+cm[j-1]][j-1]==1)?1:gcd(Gc[i][j-1],Gc[i+cm[j-1]][j-1])),
            Mn[i][j]=Min(Mn[i][j-1],Mn[i+cm[j-1]][j-1]);
        }
    int l=0,r=n-1,mid,ans,cnt=0;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid)) l=mid+1,ans=mid;
        else r=mid-1;
    }
    if(!ans){
        printf("%d %d\n",n,0);
        for(int i=1;i<=n;++i) printf("%d ",i);
    }
    else{
        for(int i=1;i+ans<=n;++i)
            if(query(i,i+ans),gc==mn) b[++cnt]=i;
        printf("%d %d\n",cnt,ans);
        for(int i=1;i<=cnt;++i)  printf("%d ",b[i]);
    }
    return 0;
}

小奇学数论

我... 表打炸了...

对于 20% 的数据,枚举 1 到 n,暴?判断素数。

对于 40% 的数据,枚举 1 到 n,判断素数的时候只需要循 环 1 ? √ n

对于 60% 的数据,筛法

对于 80% 的数据,容斥原理

对于 100% 的数据,分段 + 前缀和打表 还有个?科技 Meissel-Lehmer 算法

分块打表 打表时用的是做素数密度那道题的方法==

int cnt=0,prime[700000];bool v[N];
void primes(){
    for(ll i=2;i<=n;++i){
        if(!v[i]) v[i]=1,prime[++cnt]=i;
        for(int j=1;j<=cnt&&i*prime[j]<=n;++j){
            v[i*prime[j]]=1;
            if(!(i%prime[j])) break;
        }
    }
}

bool a[5000010];
void work(){
    m=n,n=1000000ll;primes();
    for(int i=1;i<=m/5000000;++i) ans+=table[i];
    ll L=(m/5000000ll+1)*5000000ll,R=m;
    if(!(m%5000000ll)) {printf("%lld\n",ans);return;}
    memset(a, 0, sizeof(a));
    for (int i=1;i<=cnt;++i)
        for(ll j=max(2ll,(L-1)/prime[i]+1)*prime[i];j<=R;j+=prime[i]) a[j-L]=1;
    for(ll i=L;i<=R;++i)
        if(!a[i - L]) ++ans;
    printf("%lld",ans);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n);
    if(n<=10000000){
        primes();
        printf("%d",cnt);
    }
    else work();
/*  int i=1;
    for(;i<=20000;++i) if(table[i]==2) break;
    printf("%d",i);*/
    return 0;
}

原文地址:https://www.cnblogs.com/lxyyyy/p/11738487.html

时间: 2024-11-05 21:38:13

【2019.10.25】的相关文章

【2019.10.25 OI-Killer的模拟赛】3.鸡数

题目链接 题意: 定义“鸡数”指从高位到低位单调不减的数.求$[a,b]$之间有多少个“鸡数”.$t$组询问. $1\le t\le 10^5,\; 1\le a\le b\le 2^{31}-1$ 分析: 数位DP.设$f[i][j]$表示长度为$i$,最高位是$j$的“鸡数”个数,那么$$f[i][j]=\sum\limits^9_{k=j}f[i-1][k]$$ 且$$f[1][i]=1\;(1\le i\le 9)$$ 那么对于一个长度为$l$的$n$且由低到高位写成$s_{1\dots

【2019.9.25】Za

容斥 容斥 \(\Big|\bigcup\limits_{i=1}^nS_i\Big|=\sum\limits_{m=1}^n(-1)^{m-1}\ \sum\limits_{a_i<a_{i+1}}\Big|\bigcap\limits_{i=1}^mS_{a_i}\Big|\) 不定方程非负整数解计数 不定方程\(\sum_{i=1}^n\ x_i=m\)和\(n\)个限制条件\(x_i\le b_i\) 没有限制时 其非负整数解为\(C_{m+n-1}^{m-1}\) 相当于有\(m\)个

【2019.10.18】luogu TG5动态规划进阶

树形dp P1352 没有上司的舞会 P2607 骑士(review) 对于每一个"联通快" 只有根节点有机会形成环 强制不选\(rt\)和\(rt\)的父亲 各跑一遍 P1131 时态同步(review) 贪心 显然增加深度约小的边越优 从下到上来调整 先将同一个点的儿子们延伸到一样 再往上进行一样的操作 //apio 烟火 树上背包? 一棵\(n\)个点的树,有点权.选择一个大小不超过\(K\)的联通块,使得点权和最大.\(n ≤ 2000\) \(f(x, i)\)表示\(x\)

【2019.10.8】

T1.方阵 题意:n*m的方阵,第i列j行的值为Xij,给定几个矩形的左上角和右下角,问SUM/ MAX/ MIN? 题解:我是打的前缀和求SUM,但是遇到MAX和MIN就直接跪了打的枚举,拿了40暴力分. 代码: 原文地址:https://www.cnblogs.com/jian-song/p/11634925.html

【2019.10.27】

题目 题解 T1是道睿智题,理解题意花了20min,出题人的样例给了相当没给,用自己的话翻译了下题面后发现没注意到a1也可以更改,于是就想到了读入时线型预处理下每组等差数列,结构体记下末尾的序号.编号和数列长度:再枚举数列,合并算len,ans就是max(ans,ans+len): #include<bits/stdc++.h> #define ri register int #define ll long long #define For(i,l,r) for(ri i=l;i<=r;

【2019.10.30】意料之外的小黄衫——获得小黄衫感言

前言 能在还没到期末之前就获得小黄衫确实是出乎我的意料 能被选中小黄衫真的是非常开心 在大家的印象中 我也许就是那么一个臭打游戏的男生 和大家所了解的"宅男"无异 我乐于交流却不擅长于交际 相比于侃侃而谈更偏向于喜欢默默思考 这样子的我 有什么原因能被选上小黄衫呢? 我想, 擅于观察生活的眼睛 与乐于解决问题的双手 以及一颗勇于实践的内心 这些都是主要的原因吧 在大一大二的时候我上课学习理论 期末也是理论考试 我对这样只追求分数的大学生活渐渐感到了疲惫 我所认知的计算机就该是这样子的吗

【Windows 10 IoT】为Win10 IoT镜像添加默认应用(树莓派)

[Windows 10 IoT]为Win10 IoT镜像添加默认应用(树莓派) 在Windows 10 IoT应用程序开发好之后,一般通过IoT WebManagement或者直接用vs将应用部署上去.并且执行命令iotstartup.exe add headed/headless AppxID,将应用设置为开机启动.但是,如果想基于一个开发板,量产某种硬件设备,这种方式肯定是不可行的. 我们会想到,是否可以将我们的应用直接打包到镜像中,并设置成为开机自启的默认应用呢?当然可以. 基本原理是这样

Flask学习【第10篇】:自定义Form组件

wtforms源码流程 实例化流程分析 1 # 源码流程 2 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._wtforms_meta中 3 2. 执行构造方法 4 5 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,然后将返回值添加到 self._fields[name] 中. 6 即: 7 _fields = { 8 name: wtforms.fields.core

【2018.10.4】二连爆搜+再次出锅

T1:五子棋 [题目描述] 五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏.通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜. 五子连珠是在 横线,纵线,斜线,反斜线 四个方向上形成五子及以上的连线,当出现多于五子的连珠时,也只记为一次五子连珠. 五子连珠总数. 等于棋局中的所有方向上的五子连珠连线的数量之和.我们想知道,给定一个长宽皆为 n 的棋局,白棋落在哪些点可以增加白棋五子连珠总数?对增加白棋五子连珠总数的举例说明 (A 点为我们选