[考試總結]noip模擬28
阿新 • • 發佈:2021-07-31
終於改掉了一看題目就想暴力的毛病
這次題目背景真的很有感覺。。
所以我無情地將其扒下來了。。。
“ 這個是為了發動奇蹟所必要的準備階段,是比較特殊的符卡。
明明就是準備的儀式卻做成彈幕,真是聰明啊。
” ——《魔理沙的魔法書》
“ 雖然不清楚是不是那兩人的力量
在那個風暴肆虐的夜晚,的確有一瞬
真的在那一瞬間,在雲破天開的時候
透過空隙中看到的璀璨星空,不知為何倒映眼中不能忘懷 ” ——《奇蹟召喚星辰》
“ 注視著屬於我 獨一無二的命運
席捲勁風 摧破結界
不再束縛於常識之海的我
撕裂大海 去開闢真正的道路吧
” ——《無盡的風之軌跡》
不水了。
\(T1\) 其實有個很顯然的貪心,然後這個題也就沒什麼了,然後複雜度雖然我感覺不太對,然而考場上下發的打樣例秒出了。。
所以感覺很穩。。
然而 \(T2\) 給我來了當頭一棒。。。
暴力都 \(TM\) 打不對,然後經過我 \(2h\) 的努力,終於調出來了暴力。
然後只有一點點時間的時候開的 \(T3\),然後發現題目很難懂,其實是因為太中二了。。
但是最後還是過了大樣例。。。
遺忘之祭儀
這個題目就是記錄下來附節上的所有x
的位置。
然後對給出的大圖進行遍歷,之見到一個x
就要去填滿,如果發現不合法,直接puts("No");
就行了。
%: pragma GCC optimize("O9") #include<bits/stdc++.h> using std::cout; using std::endl; #define try(i,a,b) for(register signed i=a;i<=b;++i) #define throw(i,a,b) for(register signed i=a;i>=b;--i) #define debug cout<<"debug"<<endl FILE *xinnb; int ak; void openfile() {xinnb = freopen("t.txt","r",stdin);} static const int maxn = 1e3+10,inf = 1e9+7; namespace xin { char s[maxn]; int T,n,m,hang,lie; int a[maxn][maxn]; class xin_data { public: int x,y; xin_data(){} xin_data(int x,int y):x(x),y(y){} }d[maxn*maxn];int zhi = 0; inline void outa() { try(i,1,n) { try(j,1,m) cout<<a[i][j]<<' '; cout<<endl; } cout<<endl; } inline bool check(int x,int y) { try(i,1,zhi) { register int dx = x + d[i].x - 1,dy = y + d[i].y - 1; // cout<<"dx = "<<dx<<" dy = "<<dy<<endl; // outa(); if(dx > n or dy > m or !a[dx][dy]) {return false;} a[dx][dy] = 0; } return true; } inline short main() { #ifndef ONLINE_JUDGE openfile(); #endif ak = scanf("%d",&T); while(T--) { zhi = 0; ak = scanf("%d%d%d%d",&n,&m,&hang,&lie); try(i,1,n) { ak = scanf("%s",s+1); try(j,1,m) a[i][j] = (s[j] == 'x'); } bool fir = 0; try(i,1,hang) { ak = scanf("%s",s+1); try(j,1,lie) { register int x,y; if(s[j] == 'x') { if(!fir) x = i,y = j,fir = 1; d[++zhi] = xin_data(i-x+1,j-y+1); } } } if(zhi == 0) {printf("No\n"); continue;} bool ok = 1; try(i,1,n) if(ok) try(j,1,m) { if(a[i][j]) { if(!check(i,j)) {puts("No"); ok = 0; break;} } } if(ok) puts("Yes"); } return 0; } } signed main(){return xin::main();}
客星璀璨之夜
直觀的暴力就是先列舉排列,然後再去列舉每一個方向,之後再 \(check\)
我因為自己能夠搞掉 \(n=10\) 的點,然而跑了 \(10min\)
正解首先我們推出來概率,之後再乘上每一段的 \(x_i - x_{i-1}\)。
但是細節挺多的。。
#include<bits/stdc++.h> using std::cout; using std::endl; #define try(i,a,b) for(register signed i=a;i<=b;++i) #define throw(i,a,b) for(register signed i=a;i>=b;--i) #define int long long namespace xin_io { #define scanf nb = scanf #define debug cout<<"debug"<<endl #define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<2,stdin),p1 == p2) ? EOF : *p1++ char buf[1<<20],*p1 = buf,*p2 = buf,output[100]; FILE *xinnb;int nb;typedef long long ll; typedef unsigned long long ull; void openfile() {xinnb = freopen("t.txt","r",stdin);} void outfile() {xinnb = freopen("o.txt","w",stdout);} inline int get() { register int s = 0,f = 1; register char ch = gc(); while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();} while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc();return s * f; } template<typename type>inline void write(type x,char out) { if(!x) return putchar('0'),putchar(out),void(); if(x < 0) putchar('-'),x = -x; register int cnt = 0;while(x) output[++cnt] = x % 10,x /= 10; throw(i,cnt,1) putchar(output[i] xor 48);return putchar(out),void(); } } using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7,mod = 998244353; static const ll llinf = 1e17+7; namespace xin { inline int ksm(int x,int y) { register int ret = 1; while(y) { if(y & 1) ret = ret * x % mod; x = x * x % mod; y >>= 1; } return ret % mod; } int f[maxn*3/1000][maxn*6/1000],n,x[maxn]; int jsq1,jsq2; inline short main() { #ifndef ONLINE_JUDGE openfile(); #endif n = get(); try(i,1,((n<<1)|1)) x[i] = get(); try(i,1,n) { register int er = ksm((i<<1),mod-2),yi = ksm(i,mod-2); try(j,2,(i<<1|1)) { int temp = (((i << 1) | 1) - j) >> 1; if(j & 1) (f[i][j] += f[i-1][j] * temp % mod * yi % mod + f[i-1][j-1] * er % mod + f[i-1][j-2] * er % mod + er + (i - temp - 1) * f[i-1][j-2] % mod * yi % mod) %= mod; else (f[i][j] += f[i-1][j] * temp % mod * yi % mod + f[i-1][j] *er % mod + er % mod + f[i-1][j-1] * er % mod + (i - temp - 1) * f[i-1][j-2] % mod * yi) %= mod; // cout<<"i = "<<i<<" j = "<<j<<" f[i][j] = "<<f[i][j]<<endl; } } int ans = 0; try(i,2,(n<<1 | 1)) (ans += f[n][i] * ( x[i] - x[i-1])) %= mod; cout<<ans<<endl; return 0; } } signed main(){return xin::main();}
割海成路之日
這個暫時只有 \(25pts\) 垃圾做法。
還沒想出來正解。。。
菜爆了。。。
只有 \(25pts\;code\)
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
namespace xin_io
{
#define scanf nb = scanf
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<2,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf,output[100]; FILE *xinnb;int nb;typedef long long ll; typedef unsigned long long ull;
void openfile() {xinnb = freopen("t.txt","r",stdin);} void outfile() {xinnb = freopen("o.txt","w",stdout);}
inline int get()
{
register int s = 0,f = 1; register char ch = gc(); while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc();return s * f;
}
template<typename type>inline void write(type x,char out)
{
if(!x) return putchar('0'),putchar(out),void(); if(x < 0) putchar('-'),x = -x;
register int cnt = 0;while(x) output[++cnt] = x % 10,x /= 10;
throw(i,cnt,1) putchar(output[i] xor 48);return putchar(out),void();
}
}
using namespace xin_io; static const int maxn = 3e6+10,inf = 1e9+7; static const ll llinf = 1e17+7;
namespace xin
{
class xin_edge{public:int next,ver,w;}edge[maxn];
int head[maxn],cnt = 1;
inline void add(int x,int y,int w) {edge[++cnt].ver = y; edge[cnt].w = w ; edge[cnt].next = head[x]; head[x] = cnt;}
int n,m;
int dep[maxn],f[maxn][24],fr[maxn],lg[maxn],num = 0;
std::unordered_map<int,int>e[maxn];
void pre_dfs(int x,int fa)
{
dep[x] = dep[fa] + 1;
f[++num][0] = x;
if(!fr[x]) fr[x] = num;
for(register int i=head[x];i;i=edge[i].next)
{
register int y = edge[i].ver;
if(y == fa) continue;
pre_dfs(y,x);
f[++num][0] = x;
if(!fr[x]) fr[x] = num;
}
}
void RMQ()
{
for(register int j=1;(1<<j)<=num;++j)
for(register int i=1;i+(1<<j)-1<=num;++i)
if(dep[f[i][j-1]]<dep[f[i+(1<<(j-1))][j-1]])f[i][j]=f[i][j-1];
else f[i][j]=f[i+(1<<(j-1))][j-1];
try(i,2,num) lg[i] = lg[i>>1] + 1;
}
int lca(int x,int y)
{
x = fr[x]; y = fr[y];
if(x > y) x ^= y ^= x ^= y;
int len=lg[y-x+1];
return dep[f[x][len]]<dep[f[y-(1<<len)+1][len]]?f[x][len]:f[y-(1<<len)+1][len];
}
bool ok = 0,shit = 1;
void dfs1(int x,int goal)
{
if(x == goal or !shit) return ;
for(register int i=head[x];i;i=edge[i].next)
{
register int y = edge[i].ver,z = edge[i].w;
if(dep[y] > dep[x]) continue;
if(ok and z > 1) {shit = 0; return ;}
if(z == 3) ok = 1;
dfs1(y,goal);
}
}
void dfs2(int x,int goal)
{
if(x == goal ) return ;
for(register int i=head[x];i;i=edge[i].next)
{
register int y = edge[i].ver,z = edge[i].w;
if(dep[y] > dep[x]) continue;
dfs2(y,goal);
if(ok and z > 1) {shit = 0; return ;}
if(z == 3) ok = 1;
}
}
inline bool check(int x,int y)
{
register int goal = lca(x,y); ok = 0; shit = 1;
dfs1(x,goal); dfs2(y,goal);
return shit;
}
inline short main()
{
#ifndef ONLINE_JUDGE
openfile();
#endif
n = get(); m = get();
try(i,1,n-1)
{
register int x = get(),y = get(),z = get();
add(x,y,z); e[x][y] = e[y][x] = cnt;
add(y,x,z);
}
pre_dfs(1,0); RMQ();
try(i,1,m)
{
register int x = get(),y = get(),s = get(),t = get(),ans = 0;
if(edge[e[x][y]].w xor 1) edge[e[x][y]].w--,edge[e[x][y] xor 1].w--;
write(check(t,s),' ');
try(i,1,n) if(check(i,s)) {/*cout<<"i = "<<i<<endl; */ans++;}
write(ans,'\n');
}
return 0;
}
}
signed main(){return xin::main();}