noip12
T1
类似于昨天的t3,先用单调栈求出管控区间,然后暴力求解30pts
我没取模还没开longlong,然后就爆0了
正解:
- 仍然是用单调栈求一下区间,用线段树维护一下余数,对于i所对应的区间\([l_{i},r_{i}]\) ,当然是去枚举离i近的,剩下的用线段树求解,线段树要用动态开点,不然空间会炸。
Code
#include<cstdio>
#define K 1000010
#define MAX 300010
#define re register
#define int long long
namespace OMA
{
int n,k,ans;
int a[MAX],sum[MAX];
int root[K];
int top,L[MAX],R[MAX],sta[MAX];
struct Segmnet_Tree
{
int tot;
struct TREE
{
int res;
int ls,rs;
}st[K*50];
inline void Push_up(int p)
{ st[p].res = st[st[p].ls].res+st[st[p].rs].res; }
inline void insert(int &p,int l,int r,int pos)
{
p = (!p)?++tot:p;
if(l==r)
{ st[p].res = 1; return ; }
int mid = (l+r)>>1;
if(pos<=mid)
{ insert(st[p].ls,l,mid,pos); }
else
{ insert(st[p].rs,mid+1,r,pos); }
Push_up(p);
}
inline int query(int p,int l,int r,int lp,int rp)
{
if(l<=lp&&rp<=r)
{ return st[p].res; }
int sum = 0,mid = (lp+rp)>>1;
if(l<=mid)
{ sum += query(st[p].ls,l,r,lp,mid); }
if(r>mid)
{ sum += query(st[p].rs,l,r,mid+1,rp); }
return sum;
}
}Tree;
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
inline void STACK()
{
for(re int i=1; i<=n; i++)
{
while(top&&a[sta[top]]<=a[i])
{ R[sta[top--]] = i-1; }
L[i] = sta[top]+1;
sta[++top] = i;
}
while(top)
{ R[sta[top--]] = n; }
}
signed main()
{
n = read(),k = read();
for(re int i=1; i<=n; i++)
{ (sum[i] = sum[i-1]+(a[i] = read())%k) %= k; }
STACK();
for(re int i=1; i<=n; i++)
{ a[i] %= k; Tree.insert(root[sum[i]],1,n,i); }
for(re int i=1; i<=n; i++)
{
if(L[i]==R[i])
{ continue ; }
if(R[i]-i<i-L[i])
{
for(re int j=i+1; j<=R[i]; j++)
{
if(L[i]-1)
{ ans += Tree.query(root[(sum[j]-a[i]+k)%k],L[i]-1,i-1,1,n); }
else
{
int temp = (sum[j]-a[i]+k)%k;
ans += Tree.query(root[temp],L[i],i-1,1,n);
if(!temp)
{ ans++; }
}
}
if(L[i]-1)
{ ans += Tree.query(root[sum[i-1]],L[i]-1,i-2,1,n); }
else
{
if(i-2)
{ ans += Tree.query(root[sum[i-1]],1,i-2,1,n); }
if(!sum[i-1])
{ ans++; }
}
}
else
{
for(re int j=L[i]; j<=i-1; j++)
{ ans += Tree.query(root[(sum[j-1]+a[i])%k],i,R[i],1,n); }
if(i<R[i])
{ ans += Tree.query(root[sum[i]],i+1,R[i],1,n); }
}
}
printf("%lld\n",ans);
return 0;
}
}
signed main()
{ return OMA::main();}
T2
式子很好推,结果被我一顿乱搞+瞎取模取成了10pts。
首先正难则反(来自数学课),可以先求出变量互不相同时的式子
\]
然后我就码了个快速幂,求阶乘逆元gcd,一顿乱搞30pts->10pts
此时,我自己造了几个数据,发现显然不对,于是去想如何改一下。没想出来,交了个10pts。
正解:
推出式子后,考虑约分,发现只能约2及其倍数。所以去找有多少个2。
然后有个定理 \(2^{n}-a\)和\(a\) 这俩东西中,2的个数是相等的,所以找分子中2的个数,就转换成了去找 \((m-1)!\) 中2的个数,这个可以 \(O(logm)\) 求解。
对于\(m>mod\) 此时一定有一个数为mod的倍数,所以分子为0,但答案并非这个,因是%mod意义下的0,所以直接去计算分母就好了。
\(m\le mod\) 的话,直接暴力计算就好了。
Code
#include<cstdio>
#define MAX 1000100
#define re register
#define int long long
namespace OMA
{
int n,m,a,b;
int inv,c,cnt=63;
const int p = 1e6+3;
inline int quickpow(int a,int b)
{
int ans = 1;
while(b)
{
if(b&1)
{ ans = ans*a; }
a = a*a;
b >>= 1;
}
return ans;
}
signed main()
{
scanf("%lld%lld",&n,&m);
n %= p-1;
int tmp1 = 1,tmp2 = 0;
while(cnt--)
{ tmp1 <<= 1; if(tmp1>=m){ break; } (tmp2 += (m-1)/tmp1) %= p-1; }
c = quickpow(2,n),inv = quickpow(quickpow(2,tmp2),p-2);
b = quickpow(c,(m-1)%(p-1))*inv%p;
if(m<=p)
{
a = inv;
for(re int i=1; i<=m; i++)
{ (a *= c-i) %= p; }
a = ((b-a)%p+p)%p;
printf("%lld %lld\n",a,b);
}
else
{ printf("%lld %lld\n",b,b); }
return 0;
}
}
signed main()
{ return OMA::main(); }
T3
考试的时候写了个f**k大模拟+贪心,还过了自己造的hack数据,结果程序输出全是-1 10pts好成绩
考试做法错误是显然的,比如1 0 0 0 1,我的码会输出-1,因为是从前往后扫,出现次数超过1就换下一个值,顾前不顾后,wa也正常。
正解:
我们可以设二元组(a,b),表示当前位置上的数为a,其连续的长度为b。分别设两个 \(up\)和\(down\),up为能填的最大值,down为最小值,求up应该尽量往上,down相反。
最大值即为 \(up[n].a\),序列倒着就能求出来。具体实现见code。
Code
#include<cstdio>
#define MAX 200010
#define re register
namespace OMA
{
int n,m,cnt[MAX];
int a[MAX],ans[MAX];
struct pair
{ int a,b; };
pair up[MAX],down[MAX];
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
inline int min(int a,int b)
{ return a<b?a:b; }
signed LZk()
{
n = read();
for(re int i=1; i<=n; i++)
{ a[i] = read(); }
a[1] = 1;
up[1] = down[1] = (pair){1,1};
for(re int i=2; i<=n; i++)
{
up[i] = (pair){up[i-1].a,up[i-1].b+1};
down[i] = (pair){down[i-1].a,down[i-1].b+1};
if(up[i].b>2)
{ up[i] = (pair){up[i].a+1,1}; }
if(down[i].b>5)
{ down[i] = (pair){down[i].a+1,1}; }
if(a[i])
{
if(up[i].a>a[i])
{ up[i] = (pair){a[i],2}; }
if(down[i].a<a[i])
{ down[i] = (pair){a[i],1}; }
if(up[i].a<a[i]||a[i]<down[i].a)
{ printf("-1\n"); return 0; }
}
}
if(up[n].b==1)
{ up[n] = (pair){up[n-1].a,up[n-1].b+1}; }
printf("%d\n",up[n].a);
a[n] = up[n].a,cnt[up[n].a]++;
for(re int i=n-1; i>=1; i--)
{
if(!a[i])
{
int tmp = min(a[i+1],up[i].a);
if(cnt[tmp]==5)
{ tmp--; }
a[i] = tmp;
}
cnt[a[i]]++;
}
for(re int i=1; i<=n; i++)
{ printf("%d ",a[i]); }
return 0;
}
}
signed main()
{ return OMA::LZk(); }
noip12的更多相关文章
- 20210712 noip12
考场 第一次和 hzoi 联考,成功给 sdfz 丢人 尝试戴耳罩,发现太紧了... 决定改变策略,先用1h看题,想完3题再写. T1 一下想到枚举最大值,单调栈求出每个点能作为最大值的区间,然后以这 ...
随机推荐
- buu RSA
一.分析 下载链接,发现一个公钥的文件(e,n),和一个加密过的文件 二. 公钥文件,里面一堆字母,然后后面百度,才知道需要去解开n,e 指数是e,模数是n(十六进制) 三.再通过n来分解素数,得到p ...
- Android 开发学习进程0.32 dwonloadmanager使用
downloadmanager时Android系统下载器,使用系统下载器可以避免用stream流读入内存可能导致的内存溢出问题.以下为downloadmanager初始化部分.apkurl为下载网络路 ...
- Java和C#语法对比(转)
Java C# 访问修饰符 public 修饰类.接口.变量.方法. 对所有类可见. 修饰类.接口.变量.方法. 对所有类可见. internal 无. 修饰类.接口.变量.方法. 类,接 ...
- Spring boot中相关的注解
一.相关类中使用的注解 @RestController:REST风格的控制器 @RequestMapping:配置URL和方法之间的映射 @SpringBootApplication:应用程序入口类 ...
- docker之构建镜像
构建Docker镜像有以下两种方法: 使用docker commit命令. 使用docker build命令和 Dockerfile 文件. 在这里并不推荐使用docker commit来构建镜像,而 ...
- python使用笔记25--深拷贝、浅拷贝
1.循环删除list 1 ll = [1,1,32,4,3,2,3,2,4,6,4,5,6,7,8] 2 for i in ll: 3 if i % 2 !=0: 4 ll.remove(i) 5 p ...
- redis反向代理docker容器中的rabbit mq服务
最近做的项目中用到了docker,发现docker容器还真挺好用的,可以统一来管理各种资源,项目. 但是在实际使用中就碰到下面这个问题(下面所有的应用都是在docker中启动的): 通过nginx来反 ...
- keeplived+mycat+mysql高可用读写分离水平分表(谁看谁都会)
一:环境准备: 应用 主机 mysql-master 192.168.205.184 mysql-slave 192.168.205.185 mycat-01,keeplived,jdk 192.16 ...
- nacos配置本地多个实例(伪集群)
在本地配置多个nacos实例(伪集群),一般就是配置多个nacos端口,并启动多个startup.sh脚本.网上一些博客通过修改startup.sh脚本来指定不同nacos端口,比如:./startu ...
- Apache atlas liunx环境安装部署手册
一. 背景 本文使用一台ubuntu虚拟机安装Apache-atlas,使用集成包unzip apache-atlas-2.1.0.zip进行快速安装部署,该集成包高度集成了hadoop ...