部分分很肥,正解寫得常數稍大就會和暴力乙個分,考試的時候寫什麼自己考慮。(滑稽
部分分的迴圈邊界手抖寫錯了-25 (原本暴力分中的10分都沒了啊啊啊)
沒寫掛的話應該有75,其實就是二維字首和+暴力列舉點對統計+$a[i][j]$都相等時只枚舉子矩形大小再乘上這種大小出現的次數。
正解:$(sum[r]-sum[l-1])\% k=0 \rightarrow sum[r]\% k=sum[l-1]\% k$
枚舉行數$i,j$和列數$k$,維護i行和j行之間、k列左側在%k意義下同餘矩陣的個數,用桶來實現。
#include#includeview code#include
using
namespace
std;
typedef
long
long
ll;const
int n=650
;int
n,m;
ll k,ans;
inta[n][n];
ll sum[n][n],sum1[n],cnt[
1000005
];int
read()
while(isdigit(ch))x=x*10+ch-'
0',ch=getchar();
return x*f;
}int
main()
for(int k=1;k<=m;k++)cnt[sum1[k]]=0
; }
cout
return0;
}
我考場都能想到的sb貪心。每次取出深度最大且未被覆蓋的點,在它的k級祖先上駐紮即可。前者用堆維護,後者直接暴力修改覆蓋狀態,注意向上修改時不要只遍歷和它在一條鏈上的。
正確性?讀者自證不難。(逃
#include#includeview code#include
#include
#define pa pair#define re register
using
namespace
std;
intread()
while(isdigit(ch))x=x*10+ch-'
0',ch=getchar();
return x*f;
}const
int n=100005
;int
n,k,t;
int to[n<<1],nxt[n<<1
],head[n],tot;
inline
void add(int x,int
y)int
dep[n],fa[n];
priority_queue
q;void dfs1(int x,int
deep)
return;}
intcover[n],anc,ans;
void getan(int x,int
rest)
getan(fa[x],rest-1
);
return;}
void dfs2(int x,int rest,int
f)
return;}
intmain()
dfs1(
1,1);
for(re int i=1;i<=n;i++)
q.push(make_pair(dep[i],i));
while(!q.empty())
cout
return0;
}
區間狀態反轉可以看作區間異或1,但區間操作不好處理,考慮通過差分轉化為單點操作。即把對原陣列上$[l,r]$區間的操作轉化為差分陣列上$l-1$和$r$兩個點的操作。這裡用到了異或差分:$dif[i]=a[i]\ xor\ a[i+1]$
所以問題變成了:有乙個01串,每次對其中兩個點$xor\ 1$,需要多少次把這個串的每一位都變成0。(差分陣列全0對應原陣列全1)
可以發現,消去兩個1的費用與他們之間的距離有關。bfs預處理出來後,問題再次得到轉化:每次取出一對物品,每對物品取出都有一定代價,如何取出使得代價最小。由於不亮的燈泡很少,這個問題完全可以狀壓解決。
#include#includeview code#include
#include
#include
using
namespace
std;
intread()
while(isdigit(ch))x=x*10+ch-'
0',ch=getchar();
return x*f;
}const
int n=40005
;int
n,m,k;
inta[n],op[n],dif[n];
intpos[n],sz;
int vis[n],dis[20][20
],d[n];
int find0[n<<1],dp[n<<1
];void bfs(int
node)
if(s2>=0&&!vis[s2])}}
}int
main()
for(int i=1;i<=sz;i++)
for(int s=0;s
}memset(dp,
0x3f,sizeof
(dp));
dp[0]=0
;
for(int s=0;s
for(int i=find0[s]+1;i)
}cout
<1
<1]<
return0;
}
模擬17 題解
t1 a.入陣曲 60 演算法 維護一下某一列的從第一行到這一行和二維字首和 然後列舉上下左右邊界,o n 4 100 演算法 省掉左右邊界的列舉,改為從左向右掃一邊,記錄總和 k的餘數,並放入桶中,可以發現,如果這個值出現過,那說明這個位置的總和減去那個位置的差 即這個區間 是k的正倍數 t2又是...
NOIP模擬20 題解
來自達哥的問候 究級難題,完全不可做qaq include include include using namespace std typedef long long ll int n ll a 25 b 25 c 25 d 25 ans void dfs int step,ll mdx,ll lh...
NOIP模擬16 題解
出題人大概已經去為國家處理積壓子彈了?貪心,讓每乙隻青蛙 我慫行吧 都盡量往遠跳,能到達的最遠的被踩了就跳次遠的,以此類推。可以維護乙個單調佇列,表示每只青蛙的位置 開始都是0 然後按順序掃一遍每個石頭,如果隊首的青蛙不能跳過去就放棄它直接pop掉,如果能跳就把石頭位置從隊尾push進去並pop掉隊...