11月16日——离noip还有3天[学战都市Asterisk]
来源:互联网 发布:js数组去重复的方法 编辑:程序博客网 时间:2024/04/30 23:54
今天吊车尾了……蓝瘦香菇……
于是乎,好好加油……预祝我NOIP不要吊车尾……
每日推荐
今天推荐的是学战都市Asterisk:
作为歌姬党,我就只发歌姬的图吧……好吧,还是发发其他“女主”的图吧……
再追加一张歌姬的图!!!
小说资源:
http://pan.baidu.com/s/1slaoLtF
开始干正事
LGTB 与序列
LGTB 得到了一个序列,他想在这个序列中选择一个最长的连续子序列,使得这个子序列的最大公约数等于1。请告诉他他能得到的最大长度,如果没有这样的序列,输出-1 。
输入
输入第一行包含一个整数n 代表序列大小
接下来一行,包含n 个整数a1, a2, …, an,代表序列
对于50% 的数据,1 <=n <=1000
对于100% 的数据,1<=n<=10^5,1<=ai<=10^9
输出
输出包含一个整数l,代表最长的连续子序列,如果无解请输出-1
样例
样例输入
2
7 2
样例输出
2
样例输入
3
2 2 4
样例输出
-1
思考
啊啊啊啊啊!!!!!!
我交错程序了!!
题解……
无!!
当序列长度增加的时候,GCD的大小只会变得更小或者不变,那么要求最长的GCD为1(最小)的字串,就是全串。
Ans = GCD==1? N : -1;
code
#include <set>#include <cmath>#include <stack>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cstdlib>#include <numeric>#include <vector>#include <ctime>#include <queue>#include <list>#include <map>using namespace std;int main(){ freopen("seq.in", "r", stdin); freopen("seq.out", "w", stdout); int T,n,g; scanf("%d%d",&n,&g); for(int i=1;i<n;i++){ int tmp; scanf("%d",&tmp); g=__gcd(g,tmp);//有一个内建函数…… } if(g!=1) printf("%d\n",-1); else printf("%d\n",n);}
LGTB 与桌子
LGTB 新买了一张n m 的矩(桌) 阵(子),他想给某些1 1 的小矩形染色,使得染色之后,原矩阵的每
个n n 的子矩阵中都包含恰好k 个被染色了的小矩形
他想知道有多少种染色方案能让他满足上述要求
因为答案可能很大,请输出方案数模1000000007 (109 + 7) 后的值
输入
输入第一行包含三个整数n, m, k 意义如题面所示
对于15% 的数据,1 <= n * m <= 20, n <= m
对于40% 的数据,1 ,= n <= 10, n <= m <= 1000
对于100% 的数据,1 <= n <= 100, n * m 10^18, 0 <= k <= n^2
输出
输出包含1 个整数,代表LGTB 的方案数
样例
样例输入
5 6 1
样例输出
45
样例说明
样例如图所示,如果在灰色区域染一个格子,有20 种方案。如果在两边的白色格子各染一个格子,有25 种
方案。共45 种方案
思路
数学归纳法+快速幂
题解
当前n列有k个染色的时候,假设第1列有x个染色,那么第n+1列也应该有x个染色,后面的同理。
则kn+i列的染色个数与第i列染色个数相同
那么可以分成很多个列长度为n的块同时计算(最后一块小于等于n列)
用dp(i,j)表示处理了所有块的前i列,每一块总的染色个数为j的方案数
Dp(i,j) = ∑dp(i-1,j-p) * (C(n,p)) ^ T[i]
其中T[i]表示m列中共有多少个kn+i列
用快速幂预处理(C(n,p)) ^ T[i]
Dp用O(n^4)递推
code
——来自于已经毕业的一位何神的code
ORZ ORZ ORZ
#define PROC "table"#include <cstdio>#include <memory.h>#include <algorithm>using namespace std;typedef long long qw;#ifdef WIN32#define lld "%I64d"#else#define lld "%lld"#endif#define _l (qw)#define incm(a,b) (a=(_l (a) + (b))%mod)const int maxn = 109;const int mod = 1e9 + 7;int t[2][maxn * maxn], f[maxn * maxn], c[maxn][maxn], n, k;qw m;int modPow(int a, qw x) { int s = 1; for (; x; x >>= 1, a = _l a * a % mod) if (x & 1) s = _l s * a % mod; return s;}void pre() { memset(c, 0, sizeof(c)); for (int i = 0; i < maxn; ++ i) c[i][0] = 1; for (int i = 1; i < maxn; ++ i) for (int j = 1; j <= i; ++ j) c[i][j] = (_l c[i - 1][j] + c[i - 1][j - 1]) % mod;}int main() { freopen(PROC ".in", "r", stdin); freopen(PROC ".out", "w", stdout); pre(); memset(t, 0, sizeof(t)); memset(f, 0, sizeof(f)); scanf("%d" lld "%d", &n, &m, &k); for (int i = 0; i <= n && i <= k; ++ i) { t[0][i] = modPow(c[n][i], m / n + 1); t[1][i] = modPow(c[n][i], m / n); } f[0] = 1; int c0 = m % n, c1 = n - c0; for (int i = 0; i < c0; ++ i) for (int j = k; j >= 0; -- j) { int s = 0; for (int l = 0; j - l >= 0 && l <= n; ++ l) if (f[j - l]) incm(s, _l f[j - l] * t[0][l]); f[j] = s; } for (int i = 0; i < c1; ++ i) for (int j = k; j >= 0; -- j) { int s = 0; for (int l = 0; j - l >= 0 && l <= n; ++ l) if (f[j - l]) incm(s, _l f[j - l] * t[1][l]); f[j] = s; } printf("%d\n", f[k]);}
LGTB 与正方形
LGTB 最近迷上了正方形,现在他有n 个在二维平面上的点,请你告诉他在这些点中选4 个点能组成四条边
都平行于坐标轴的正方形的方案数有多少
输入
输入第一行包含一个整数n,代表点的数量
接下来n 行每行包含两个整数xi, yi,代表点的坐标
对于10% 的数据,1 <= n <= 50
对于30% 的数据,1 <= n <= 1000
对于100% 的数据,1 <= n <= 10^5,0 <= xi, yi <= 10^5
数据保证没有两点在同一位置
输出
输出包含一个整数代表方案数
样例
样例输入
5
0 0
0 2
2 0
2 2
1 1
样例输出
1
样例输入
9
0 0
1 1
2 2
0 1
1 0
0 2
2 0
1 2
2 1
样例输出
5
思路
多方向暴力,例横、纵、斜三种方式遍历,找最优方式n^2,可以过,注意打哈希,set要超时,STL较慢。
题解
标答
——就是上诉方式,横向与纵向搜索
#include <set>#include <cmath>#include <stack>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cstdlib>#include <numeric>#include <vector>#include <ctime>#include <queue>#include <list>#include <map>#define pi acos(-1.0)#define INF 0x3f3f3f3f#define clr(x) memset(x,0,sizeof(x));#define clrto(x,siz,y) for(int xx=0;xx<=siz;xx++) x[xx]=y;#define clrset(x,siz) for(int xx=0;xx<=siz;xx++) x[xx]=xx;#define clr_1(x) memset(x,-1,sizeof(x));#define clrmax(x) memset(x,0x3f,sizeof(x));#define clrvec(x,siz) for(int xx=0;xx<=siz;xx++) x[xx].clear();#define fop2 freopen(".in","r",stdin); //freopen(".out","w",stdout);#define fop freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);#define myprogram By_135678942570#define clrcpy(x,siz,y) for(int xx=0;xx<siz;xx++) x[xx]=y[xx];#define pb push_backusing namespace std;struct point{ int x,y;}P[100011];int SIZ=400;struct hash_map{ const static int mod=100007; int head[mod]; struct hash_tables { long long key; int val; int next; }ele[100007]; int N; int getHash(long long x) { return x%mod; } void init() { memset(head,255,sizeof(head)); N=0; } int fint(long long x) { for(int i=head[getHash(x)];i!=-1;i=ele[i].next) if(ele[i].key==x) return i; return -1; } void insert(long long x) { int tmp=getHash(x); ele[N].key=x; ele[N].val=0; ele[N].next=head[tmp]; head[tmp]=N++; } int& operator [](long long x) { int tmp=fint(x); if(tmp==-1) { insert(x); return ele[N-1].val; } else return ele[tmp].val; }}HT;vector<int>row[100111];vector<int>GREAT;vector<int>LESS;int main(){ // fop; freopen("square.in", "r", stdin); freopen("square.out", "w", stdout); HT.init(); int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&P[i].x,&P[i].y); row[P[i].x].pb(P[i].y); HT.insert(P[i].x*1000003ll+P[i].y); } for(int i=0;i<=100000;i++) if(row[i].size()>=SIZ) GREAT.pb(i); else if(row[i].size()>0) LESS.pb(i); int res=0; for(int i=0;i<LESS.size();i++) { int rowid=LESS[i]; for(int j=0;j<row[rowid].size();j++) for(int k=j+1;k<row[rowid].size();k++) { int x1=rowid; int y1=row[rowid][j],y2=row[rowid][k]; int x2=x1+abs(y1-y2); int x22=x1-abs(y1-y2); int f1=HT.fint(x2*1000003ll+y1); int f2=HT.fint(x2*1000003ll+y2); if(f1!=-1&&f2!=-1) { res++; } if(x22>=0&&row[x22].size()>=SIZ) { f1=HT.fint(x22*1000003ll+y1); f2=HT.fint(x22*1000003ll+y2); if(f1!=-1&&f2!=-1) res++; } } } for(int i=0;i<GREAT.size();i++) sort(row[GREAT[i]].begin(),row[GREAT[i]].end()); for(int i=0;i<GREAT.size();i++) for(int j=i+1;j<GREAT.size();j++) { int x1=GREAT[i]; int x2=GREAT[j]; int len=abs(x1-x2); int ii=0,jj=0; while(ii<row[x1].size()&&jj<row[x2].size()) { if(row[x1][ii]==row[x2][jj]) { int f1=HT.fint(x1*1000003ll+row[x1][ii]+len); int f2=HT.fint(x2*1000003ll+row[x2][jj]+len); if(f1!=-1&&f2!=-1) res++; ii++,jj++; } else if(row[x1][ii]>row[x2][jj]) jj++; else ii++; } } printf("%d\n",res);}
利用set的做法
*注:只有70%
——此程序为邓**所创,(我帮他调试的……)
#include<set>#include<queue>#include<cstdio>#include<vector>#include<cstring>#include<iostream>#include<algorithm>using namespace std;struct node{ int x,y; bool operator<(const node&a)const { if(a.x!=x)return a.x>x; else return a.y>y; }}gg[100005];int small[100005],big[100005],low;int high,bb[100005],vis[100005];set<node>judge;vector<int>ma[100005];inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int main(){ freopen("square.in","r",stdin); freopen("square.out","w",stdout); int n=read(),maxn=0; for(int i=1;i<=n;i++) { gg[i].x=read();gg[i].y=read(); ma[gg[i].x].push_back(gg[i].y); judge.insert(gg[i]); maxn=max(maxn,gg[i].x); vis[gg[i].x]=1; } for(int i=0;i<=maxn;i++) if(vis[i]) { int num=ma[i].size(); if(num<400) small[++low]=i; else { big[++high]=i; bb[i]=1; } sort(ma[i].begin(),ma[i].end()); } int ans=0; for(int i=1;i<=low;i++) for(int j=0;j<ma[small[i]].size();j++) for(int k=j+1;k<ma[small[i]].size();k++) { int tmp=small[i]-(ma[small[i]][k]-ma[small[i]][j]); if(tmp) if(judge.count((node){tmp,ma[small[i]][j]})) if(judge.count((node){tmp,ma[small[i]][k]})) if(bb[tmp]==1) ans++; tmp=small[i]+(ma[small[i]][k]-ma[small[i]][j]); if(tmp<=maxn) if(judge.count((node){tmp,ma[small[i]][j]})) if(judge.count((node){tmp,ma[small[i]][k]})) ans++; } for(int i=1;i<=high;i++) for(int j=i+1;j<=high;j++) { int op1=0,op2=0; while(op1<ma[big[i]].size()&&op2<ma[big[j]].size()) { if(ma[big[i]][op1]>ma[big[j]][op2]) op2++; else if(ma[big[i]][op1]<ma[big[j]][op2]) op1++; else { int tmp=big[j]-big[i]; if(judge.count((node){big[i],ma[big[i]][op1]+tmp})) if(judge.count((node){big[j],ma[big[j]][op2]+tmp})) ans++; op1++;op2++; } } } printf("%d",ans); return 0;}
何jiaao的SBT
ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ ORZ
——除了谢mj大神外,他是我见到的又一个手写平衡二叉树的人
#define PROC "square"#include <cstdio>#include <memory.h>#include <algorithm>using namespace std;struct point { int x, y;};inline bool cmpPoint(const point& a, const point& b) { return a. x < b. x || (a. x == b. x && a. y < b. y);}typedef long long qw;#ifdef WIN32#define lld "%I64d"#else#define lld "%lld"#endifconst int maxn = 100009;const int inf = 0x3f3f3f3f;namespace sbt { //namespace你怕不怕!!!sbt你怕不怕!!! const int maxnd = maxn * 3; int ls[maxnd], rs[maxnd], sz[maxnd], vl[maxnd], tn; void init() { tn = 0; sz[0] = 0; } inline void lRot(int& p) { int q = rs[p]; rs[p] = ls[q]; ls[q] = p; sz[p] = sz[ls[p]] + sz[rs[p]] + 1; sz[q] = sz[ls[q]] + sz[rs[q]] + 1; p = q; } inline void rRot(int& p) { int q = ls[p]; ls[p] = rs[q]; rs[q] = p; sz[p] = sz[ls[p]] + sz[rs[p]] + 1; sz[q] = sz[ls[q]] + sz[rs[q]] + 1; p = q; } inline void maintain(int& p, bool d) { if (d) { if (sz[ls[p]] + 1 > sz[rs[p]]) rRot(p); } else if (sz[ls[p]] < sz[rs[p]] + 1) lRot(p); } void ins(int& p, int v) { if (!p) { p = ++ tn; ls[p] = 0; rs[p] = 0; sz[p] = 1; vl[p] = v; } else { if (v < vl[p]) ins(ls[p], v); else ins(rs[p], v); ++ sz[p]; maintain(p, v < vl[p]); } } int prv(int p, int v) { if (!p) return -inf; else if (v > vl[p]) return max(vl[p], prv(rs[p], v)); else return prv(ls[p], v); } int lower(int p, int v) { if (!p) return -inf; else if (v == vl[p]) return v; else if (v > vl[p]) return max(vl[p], lower(rs[p], v)); else return lower(ls[p], v); }};int n;qw ans;point a[maxn];int rx[maxn], ry[maxn], rk[maxn * 2];void addNode(int* rt, int p, int v) { sbt :: ins(rt[p], v);}qw countSqu(int x, int y) { int i = sbt :: prv(rx[x], y); int j = sbt :: prv(ry[y], x); int k = sbt :: prv(rk[y - x + maxn], x); qw s = 0; while (i > -inf && j > -inf && k > -inf) if (y - i == x - j && j == k) { //printf("(%d, %d), (%d, %d)\n", j, i, x, y); ++ s; i = sbt :: prv(rx[x], i); j = sbt :: prv(ry[y], j); k = sbt :: prv(rk[y - x + maxn], k); } else { int vm = max(max(y - i, x - j), x - k); if (y - i < vm) i = sbt :: lower(rx[x], y - vm); if (x - j < vm) j = sbt :: lower(ry[y], x - vm); if (x - k < vm) k = sbt :: lower(rk[y - x + maxn], x - vm); } return s;}int main() { freopen(PROC ".in", "r", stdin); freopen(PROC ".out", "w", stdout); memset(rx, 0, sizeof(rx)); memset(ry, 0, sizeof(ry)); memset(rk, 0, sizeof(rk)); sbt :: init(); scanf("%d", &n); for (int i = 0; i < n; ++ i) scanf("%d%d", &a[i]. x, &a[i]. y); sort(a, a + n, cmpPoint); for (int i = 0; i < n; ++ i) { ans += countSqu(a[i]. x, a[i]. y); addNode(rx, a[i]. x, a[i]. y); addNode(ry, a[i]. y, a[i]. x); addNode(rk, a[i]. y - a[i]. x + maxn, a[i]. x); } printf(lld "\n", ans);}
总结
今天就GG了
然后对于数论的知识我认为应该进一步在代码实现上加强。
另外,dp的灵活运用上仍有不足,搜索的方法上还可以有进一步突破。
- 11月16日——离noip还有3天[学战都市Asterisk]
- 11月8日——离noip还有11天
- 11月7日——离noip还有12天
- 11月9日——离noip还有10天
- 11月13日——离noip还有6天【今天”认真“总结】
- 11月14日——离noip还有5天[Darker Than Black]
- 11月15日——离noip还有4天[Black Bullet]
- 11月17日——离noip还有2天[绯弹的亚里亚]
- 11月11日——离noip还有8天【又是一年光棍节】[被狙击的学园]
- 11月12日——离noip还有7天[云之彼端,约定的地方]
- 11月10日——离noip还有9天【你的名字……】与[一个神奇的函数]
- 3月16日——培训第81天
- 11月23日——培训第3天
- 3月11日——培训第77天
- 3月29日开始学Java
- 11月16日
- 3月16日
- 3月16日
- container_of实现分析
- .NET创建winform透明窗体
- 如何导入libs 需要在gradle project
- 关于RTB实时竞价的基本原理
- EasyUI Combox过滤
- 11月16日——离noip还有3天[学战都市Asterisk]
- 顺序队列
- PostgreSQL之函数和操作符
- 【NOIP2015】信息传递 dfs
- Android开发之TextView垂直显示List列表数据
- 神经网络:Residual Network
- php单双引号对变量解析的影响以及php向mysql插入数据时的变量解析问题详解
- ReactNative 广播机制
- 哈夫曼树的总结