rt
代码如下:
#include <bits/stdc++.h>
#define For( i , j , k ) for( ll i = ( j ) ; i <= ( k ) ; ++ i )
#define For__( i , j , k ) for( ll i = ( j ) ; i >= ( k ) ; -- i )
#define Fore( i , j , k ) for( ll i = j ; i ; i = k )
#define ll long long
#define lf double
#define llf long double
using namespace std;
//-------------------------Fastio-------------------------//
namespace Fread {
const int SIZE = 1 << 16;
char buf[ SIZE ], *S, *T;
inline char getchar() {
if ( S == T ) {
T = ( S = buf ) + fread( buf , 1 , SIZE , stdin );
if ( S == T ) return '\n';
}
return *S ++;
}
}
namespace Fwrite {
const int SIZE = 1 << 16;
char buf[ SIZE ], *S = buf, *T = buf + SIZE;
inline void flush() {
fwrite( buf , 1 , S - buf , stdout );
S = buf;
}
inline void putchar(char c) {
*S ++ = c;
if ( S == T ) flush();
}
struct NTR {
~ NTR() {
flush();
}
} ztr;
}
#ifdef ONLINE_JUDGE
#define getchar Fread :: getchar
#define putchar Fwrite :: putchar
#endif
namespace Fastio{
struct Fast_read{
template< typename T >
Fast_read& operator >> ( T &num ){
num = 0 ; T f = 1 ; char c = ' ';
while( c < '0' || c > '9' ) if( ( c = getchar() ) == '-' ) f = -1;
while( c >= '0' && c <= '9' ) num = ( num << 1 ) + ( num << 3 ) + ( c ^ 48 ) , c = getchar();
num *= f;
return *this;
}
Fast_read& operator >> ( char &c ){
c = getchar();
while( c == '\n' || c == '\r' || c == ' ' ) c = getchar();
return *this;
}
Fast_read& operator >> ( char *str ){
ll len = 0 ; char c = ' ';
while( c == '\n' || c == '\r' || c == ' ' ) c = getchar();
str[ len ] = c;
while( c != '\n' && c != '\r' && c != ' ' ) str[ ++ len ] = getchar();
str[ ++ len ] = 0;
return *this;
}
Fast_read& operator >> ( string str ){
ll len = 0 ; char c = ' ';
while( c == '\n' || c == '\r' || c == ' ' ) c = getchar();
str[ len ] = c;
while( c != '\n' && c != '\r' && c != ' ' ) str[ ++ len ] = getchar();
str[ ++ len ] = 0;
return *this;
}
} cin;
struct Fast_write{
char putchar_use_char[ 1035 ]; ll cnt_putchar;
template< typename T >
void write_use_only( T t_num ){
ll num = t_num;
do{
putchar_use_char[ ++ cnt_putchar ] = num % 10 + '0';
num /= 10;
}while( num );
For__( i , cnt_putchar , 1 )
putchar( putchar_use_char[ i ] );
return ;
}
template < typename T >
Fast_write& operator << ( T t_num ){
cnt_putchar = 0;
ll num = t_num;
if( num < 0 ){
putchar( '-' );
num = -num;
}
write_use_only( num );
return *this;
}
Fast_write& operator << ( char c ){
putchar( c );
return *this;
}
Fast_write& operator << ( char *str ){
ll cnt = 0;
while( str[ cnt ] ) putchar( str[ cnt ++ ] );
return *this;
}
Fast_write& operator << ( const char *str ){
ll cnt = 0;
while( str[ cnt ] ) putchar( str[ cnt ++ ] );
return *this;
}
} cout;
}
#define cin Fastio :: cin
#define cout Fastio :: cout
#define endl '\n'
//-------------------------Fastio end-------------------------//
const ll maxn = 2e5 + 5;
const ll maxphi = 105;
ll n , m , mod , c;
ll a[ maxn ];
inline ll get_phi( ll x ){
ll sqr = sqrt( x ) + 1;
ll ans = x;
For( i , 2 , sqr )
if( x % i == 0 ){
ans = ans / i * ( i - 1 );
while( x % i == 0 ) x /= i;
}
if( x > 1 )
ans = ans / x * ( x - 1 );
return ans;
}
ll max_tag;
ll power_0[ maxphi ][ maxn ] , power_1[ maxphi ][ maxn ] , phi[ maxphi ];
bool is_mod_0[ maxphi ][ maxn ] , is_mod_1[ maxphi ][ maxn ];
ll size;
inline void power_init(){
For( i , 1 , 100 )
phi[ i ] = 1;
ll x = mod;
phi[ 0 ] = mod;
while( x != 1 ){
x = get_phi( x );
phi[ ++ max_tag ] = x;
}
phi[ ++ max_tag ] = 1;
size = 32768;
For( i , 0 , max_tag ){
power_0[ i ][ 0 ] = power_1[ i ][ 0 ] = 1;
For( j , 1 , size ){
power_0[ i ][ j ] = power_0[ i ][ j - 1 ] * c;
if( power_0[ i ][ j ] >= phi[ i ] ){
power_0[ i ][ j ] %= phi[ i ];
is_mod_0[ i ][ j ] = true;
}
is_mod_0[ i ][ j ] |= is_mod_0[ i ][ j - 1 ];
}
For( j , 1 , size ){
power_1[ i ][ j ] = power_1[ i ][ j - 1 ] * power_0[ i ][ size ];
if( power_1[ i ][ j ] >= phi[ i ] ){
power_1[ i ][ j ] %= phi[ i ];
is_mod_1[ i ][ j ] = true;
}
is_mod_1[ i ][ j ] |= is_mod_1[ i ][ j - 1 ];
}
}
return ;
}
bool is_mod_flag;
inline ll fastest_pow( ll b , ll depth ){
is_mod_flag = false;
ll use_0 = b & 32767 , use_1 = b >> 15;
ll res = power_0[ depth ][ use_0 ] * power_1[ depth ][ use_1 ];
if( res >= phi[ depth ] ){
res %= phi[ depth ];
is_mod_flag = true;
}
else
is_mod_flag |= is_mod_0[ depth ][ use_0 ] | is_mod_1[ depth ][ use_1 ];
return res;
}
inline ll solve( ll x , ll depth , ll ends ){
is_mod_flag = false;
//if( phi[ depth ] == 1 ) return 0;
if( depth == ends ){
if( x >= phi[ depth ] ){
is_mod_flag = true;
x %= phi[ depth ];
}
return x;
}
ll res = solve( x , depth + 1 , ends );
return fastest_pow( res + ( ll )( is_mod_flag ) * phi[ depth + 1 ] , depth );
}
namespace Line_Tree{
#define ls ( p << 1 )
#define rs ( p << 1 | 1 )
struct Tree{
ll sum , tag;
Tree( ll sum_ = 0 , ll tag_ = 0 ){
sum = sum_;
tag = tag_;
}
Tree operator + ( const Tree &x ) const{
Tree res;
res.sum = sum + x.sum;
while( res.sum >= mod ) res.sum -= mod;
res.tag = min( tag , x.tag );
return res;
}
}trees[ maxn << 2 ];
inline void push_up( ll p ){
trees[ p ] = trees[ ls ] + trees[ rs ];
return ;
}
inline void f( ll l , ll r , ll p ){
++ trees[ p ].tag;
trees[ p ].sum = solve( a[ l ] , 0 , trees[ p ].tag );
return ;
}
inline void build( ll l , ll r , ll p ){
if( l == r ){
trees[ p ] = Tree( a[ l ] % mod , 0 );
return ;
}
ll mid = l + r >> 1;
build( l , mid , ls );
build( mid + 1 , r , rs );
push_up( p );
return ;
}
inline void update( ll l , ll r , ll x , ll y , ll p ){
if( trees[ p ].tag > max_tag ) return ;
if( l == r ){
f( l , r , p );
return ;
}
ll mid = l + r >> 1;
if( x <= mid ) update( l , mid , x , y , ls );
if( mid < y ) update( mid + 1 , r , x , y , rs );
push_up( p );
return ;
}
inline ll query( ll l , ll r , ll x , ll y , ll p ){
if( x <= l && r <= y )
return trees[ p ].sum;
ll mid = l + r >> 1;
ll res = 0;
if( x <= mid ) res += query( l , mid , x , y , ls );
if( mid < y ) res += query( mid + 1 , r , x , y , rs );
while( res >= mod ) res -= mod;
return res;
}
#undef ls
#undef rs
}
int main(){
cin >> n >> m >> mod >> c;
For( i , 1 , n )
cin >> a[ i ];
power_init();
Line_Tree :: build( 1 , n , 1 );
//cout << solve( 2 , 0 , 13 ) << endl;
ll opt , l , r;
For( i , 1 , m ){
cin >> opt >> l >> r;
if( l > r ) swap( l , r );
if( !opt )
Line_Tree :: update( 1 , n , l , r , 1 );
else cout << Line_Tree :: query( 1 , n , l , r , 1 ) << endl;
}
return 0;
}
此代码AC但是第二个样例过不去,求调/kel