2017.3.1 xiaoyimi测试

本文通过一道具体题目,介绍了从基础算法逐步升级到高级算法的过程,包括30分的基本解法及代码实现,进而深入探讨了更高分的解题思路,如NNT+数位dp等,并给出了一种复杂度较高的线段树解法。


第一题太亏了、、

TMD p竟然是定值、那还输入NM啊、、、

样例p=4还是错的、、、

实际上看到这个题就已经有了30分做法,也有了一点正解的思路

但是、、、tmd p是定值、、、

感人的爆0了



30分做法:


30分代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define ll int
ll x,y,n,i,p;
long long ans;
ll tong[300001];
int ni[300001];
ll jilu;
ll lin;


long long quai(long long a,long long b)
{
long long daan=1;
while(b!=0)
{
if(b%2==1)daan=daan*a%p;
b/=2;
a=(a*a)%p;
}


return daan;
}
int main()
{
freopen("tyrrell.in","r",stdin);
freopen("tyrrell.out","w",stdout);
cin>>n>>p;
ans=1;
tong[1]++;
for(i=1;i<p;i++)ni[i]=quai(i,p-2);
for(i=1;i<=n;i++)
{    
 // if(i==n/2)cout<<"pp"; 
lin=n-i+1;
  if(!(lin%p))
{
lin=lin/p%p;
jilu++;
}
 
ans=1ll*ans*lin%p;


if(!(i%p))
{
ans=1ll*ans*ni[i/p%p]%p;
jilu--;
}else ans=1ll*ans*(ni[i%p])%p;
if(jilu>0){tong[0]++;}else {tong[ans]++;}
}
for(i=0;i<p;i++)
{
tong[i]%=29;
if(tong[i]>=10)
{
printf("%c",tong[i]-10+'A');
}else printf("%d",tong[i]);


}

}



更高分做法:NNT+数位dp:

没学、












此题有线段树做法,即


会了吧?一个简单的前缀和+两颗线段树、

但很慢且不好打而且不会维护(至少对于我)


然后上巨难理解的代码:



#include <iostream>
#include <cstdio> 
#include <cstring> 
#include <algorithm> 
#define rep(i, b) for(int i=0,nn=int(b); i<nn;++i) 
#define REP(i,a,b) for(int i=int(a),nn=int(b);i<=nn;++i)
#define VEP(i,a,b) for(int i=int(a),nn=int(b);i>=nn;--i) 
typedef long long ll; 
using namespace std; 
const int N = 100010; 
struct qury { 
int tp, l, r, d, tm; 
qury(int tp=0,int l=0,int r=0,int d=0,int tm=0) 
:tp(tp), l(l), r(r), d(d), tm(tm){}
} qy[N]; 
int xbt[N], ybt[N], abt[N], lod[N], rod[N], px[N], py[N];
int _x, _y, __x, __y, n, m, as1[N], as2[N]; 


inline void in(int &x) { 
char ch=getchar(); int f=1; 
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; 
for (x=0; ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-48; 
x *= f; 

inline bool lcmp(int a, int b) { return qy[a].l < qy[b].l; } 
inline bool rcmp(int a, int b) { return qy[a].r < qy[b].r; } 


inline void xbt_ad(int x,int v) {for(;x<=m;x+=x&(-x))xbt[x]+=v;}
inline void ybt_ad(int x,int v) {for(;x<=m;x+=x&(-x))ybt[x]+=v;}
inline void abt_ad(int x,int v) {for(;x<=m;x+=x&(-x))abt[x]+=v;}
inline int xbt_qy(int x,int sm=0) {for(;x;x-=x&(-x))sm+=xbt[x];return sm;}
inline int ybt_qy(int x,int sm=0) {for(;x;x-=x&(-x))sm+=ybt[x];return sm;}
inline int abt_qy(int x,int sm=0) {for(;x;x-=x&(-x))sm+=abt[x];return sm;}


inline void come(qury ths) { 
int tp=ths.tp, d=ths.d, tm=ths.tm; 
if (tp==1) xbt_ad(tm, d); 
if (tp==2) ybt_ad(tm, d); 
if (tp==3) as1[tm] = abt_qy(tm);
}
inline void leave(qury ths) { 
int tp=ths.tp, d=ths.d, tm=ths.tm; 
if (tp==1) xbt_ad(tm, -d); 
if (tp==2) ybt_ad(tm, -d); 
if (tp==3) as2[tm] = abt_qy(tm);

inline void contribute(int x, int y) { 
int xl, xr, yl, yr, l, r, mid, tl, tr; 
l = 0, r = m, xl = m+1; 
while (l <= r) { mid = (l+r)>>1; 
if (x + xbt_qy(mid)>=_x) xl=mid, r=mid-1; 
else l = mid+1; 

l = 0, r = m, xr = -1; 
while (l <= r) { mid = (l+r)>>1; 
if (x + xbt_qy(mid)<=__x) xr=mid, l=mid+1;
else r = mid-1; 

l = 0, r = m, yl = m+1; 
while (l <= r) { mid = (l+r)>>1; 
if (y + ybt_qy(mid)>=_y) yl=mid, r=mid-1; 
else l = mid+1; 

l = 0, r = m, yr = -1; 
while (l <= r) { mid = (l+r)>>1; 
if (y + ybt_qy(mid)<=__y) yr=mid, l=mid+1; 
else r = mid-1; 

tl = max(xl, yl), tr = min(xr, yr); 
if (tl < 1) tl=1; if (tr > m) tr = m; 
if (tl > tr) return; 
abt_ad(tl, 1) , abt_ad(tr+1, -1); 
}
int main() { 
freopen("particle.in", "r", stdin); 
freopen("particle.out", "w", stdout); 
in(n), in(_x), in(_y), in(__x), in(__y);//读入 
REP(i, 1, n) in(px[i]), in(py[i]); 
in(m); REP(i, 1, m) {
in(qy[i].tp), in(qy[i].l), in(qy[i].r); 
if (qy[i].tp != 3) in(qy[i].d); 
qy[i].tm = i, lod[i]=i, rod[i]=i; 

sort(lod+1, lod+1+m, lcmp);
sort(rod+1, rod+1+m, rcmp); 
int x, y, li=0, ri=0;
REP(i, 1, n) { x=px[i], y=py[i];  
while (li < m && qy[lod[li+1]].l<=i) come(qy[lod[++li]]);
contribute(x, y); 
while (ri < m && qy[rod[ri+1]].r<=i) leave(qy[rod[++ri]]);

REP(i, 1, m) if (qy[i].tp==3) printf("%d\n", as2[i]-as1[i]); 
return 0; 

扫描线+树状数组*3+差分**3+二分+双排序离散+3重判定

这个码理解了,思维层次就会上升很大的一个高度、


理解难度直逼TA 的 running


模拟推了好几遍(ps:模拟代码真的不是理解代码的一个好方法)

读着都快哭了、、













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值