中间件(middleware)

描述:Middlewares 是修改 Django request 或者 response 对象的钩子。

在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件。

如图为系统默认自带中间件:

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

中间件中可以定义五个方法,分别是:

process_request(self,request) :  请求来时执行,不写时直接跳过,执行下一个中间件;当有return HttpResonse时,下面中间件不再执行

process_view(self, request, callback, callback_args, callback_kwargs)  :  先执行process_request,执行完后,再从起始执行proces_view

process_template_response(self,request,response)  :  如果Views中的函数返回的对象中,具有render方法,此方法执行

process_exception(self, request, exception)  :  异常触发执行,当views.py函数执行出错后,此方法执行;出错时,最低层的exception优先级最高,执行最近的一个,然后执行respnse方法

process_response(self, request, response)  :  请求返回时执行,不写时直接跳过,执行下一个中间件;当有return HttpResonse时,会替换原数据
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

关于中间件之process_request,process_response

当用户发起请求的时候会依次按顺序经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,

views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者

自定义中间件

定义一个类,但是必须继承MiddlewareMixin,项目文件下创建一个Code目录,并在下面创建a1.py代码例子如下:

from django.utils.deprecation import MiddlewareMixin

class Row1(MiddlewareMixin):
def process_request(self,requset):
print('1号请求')
def process_response(self,requset,response):
print('1号收到')
return response class Row2(MiddlewareMixin):
def process_request(self,requset):
print('2号请求')
def process_response(self,request,response):
print('2号收到')
return response class Row3(MiddlewareMixin):
def process_request(self,requset):
print('3号请求')
def process_response(self,request,response):
print('3号收到')
return response

Code/a1.py

注册中间件

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'Code.a1.Row1','Code.a1.Row2','Code.a1.Row3' #
]

project/settings.py

urls,views函数

from django.conf.urls import  url
from app01 import views urlpatterns = [
url(r'^login/',views.login),
url(r'^index/',views.index),
url(r'^logout/',views.logout),
url(r'^test/',views.test), #new
]

project/urls.py

def test(request):
print('收到')
return HttpResponse('OK!')

app01/views.py

效果展示:

想下,如果2号请求不想继续往3号请求传递信息,直接回传个值会出现什么结果???

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse #new class Row1(MiddlewareMixin):
def process_request(self,requset):
print('1号请求')
def process_response(self,requset,response):
print('1号收到')
return response class Row2(MiddlewareMixin):
def process_request(self,requset):
print('2号请求')
return HttpResponse('我回去了啊!') #new
def process_response(self,request,response):
print('2号收到')
return response class Row3(MiddlewareMixin):
def process_request(self,requset):
print('3号请求')
def process_response(self,request,response):
print('3号收到')
return response

Code/a1.py

原理图:

备注:直接执行同级的process_response,然后依次返回到请求者,Django版本1.10之后,而不是从最低层process_response开始执行

关于中间件之process_view

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse #new class Row1(MiddlewareMixin):
def process_request(self,requset):
print('1号请求') def process_view(self, request, callback, callback_args, callback_kwargs):
print('视图1函数') def process_response(self,requset,response):
print('1号收到')
return response class Row2(MiddlewareMixin):
def process_request(self,requset):
print('2号请求')
# return HttpResponse('我回去了啊!') def process_view(self, request, callback, callback_args, callback_kwargs):
print('视图2函数') def process_response(self,request,response):
print('2号收到')
return response class Row3(MiddlewareMixin):
def process_request(self,requset):
print('3号请求') def process_view(self, request, callback, callback_args, callback_kwargs):
print('视图3函数') def process_response(self,request,response):
print('3号收到')
return response

Code/a1.py

打印结果

1号请求
2号请求
3号请求
视图1函数
视图2函数
视图3函数
收到
3号收到
2号收到
1号收到

CSRF(Cross Site Request Forgery)

描述:CSRF的攻击:用户在本地还保存A1网站的cookie,再次通过A2网站上的链接请求A1网站时,浏览器就会自动将A1网站对应的cookie加上,这样A1网站就会认为这个请求是用户合法请求而进行处理。

解决方法:

Django引用了CSRF防护机制,用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同才可通过;如果POST请求中没有token随机字符串,则返回403拒绝服务。

settings.py中配置文件:

MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
]

project/settings.py

views视图

def login(request):
# from django.conf import settings
# print(settings.CSRF_HEADER_NAME)
# HTTP_X_CSRFTOKEN
# X-CSRFtoken if request.method == "GET":
return render(request, 'login.html')
elif request.method == "POST":
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'root' and pwd == '':
# 1.生成随机字符串
# 2.写到用户浏览器cookie
# 3.保存到session
# 4.在随机字符串对应的字典中设置相关内容...
# session中创建值,运行前,需要执行python manage.py makemigrations/migrate,数据储存在数据库中
request.session['username'] = user
request.session['is_login'] = True
if request.POST.get('rmb') == "":
request.session.set_expiry(15) #15秒
# 默认是2周时间,此处设置超时时间15秒
return redirect('/index/')
else:
return render(request, 'login.html') def index(request):
# session中获取值
if request.session.get('is_login',None):
return render(request,'index.html',{'username':request.session['username']})
else:
return HttpResponse('没有验证成功! ') def logout(requset):
# del requset.session['username']#清空某一个
requset.session.clear()
return redirect('/login/')

app01/views.py

template中form表单添加{%csrf_token%}标签

<form action="/login/" method="POST">
{% csrf_token %}
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<input type="checkbox" name="rmb" value=""/>免登陆15秒
<input type="submit" value="提交"/>
</form>

templates/login.html

如果是js提交的post请求,需要添加header X-CSRFToken(在原login.html上面增加)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="POST">
{% csrf_token %}
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<input type="checkbox" name="rmb" value=""/>免登陆15秒
<input type="submit" value="提交"/>
<input id="btn1" type="button" value="按钮"/>
<input id="btn2" type="button" value="按钮"/>
</form>
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
$(function () {
//xhr的意思,对象
//obj = XMLHttpRequest()
//obj.open()
//obj.send() $.ajaxSetup({ //全局配置,所有Ajax请求都先执行下面操作
beforeSend:function (xhr,settings) {
xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken'));
}
}); $('#btn1').click(function () {
$.ajax({
url:'/login/',
type:"POST",
data:{'user':'root','pwd':''},
//headers:{'X-CSRFtoken':$.cookie('csrftoken')},
success:function (arg) { }
})
}); $('#btn2').click(function () {
$.ajax({
url:'/login/',
type:"POST",
data:{'user':'root','pwd':''},
//headers:{'X-CSRFtoken':$.cookie('csrftoken')},
success:function (arg) { }
})
});
})
</script>
</body>
</html>

templates/login.html

全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

  @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

  @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件

缓存

Django中提供了6种缓存方式:

  • 开发调试
  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)
  • Memcache缓存(pylibmc模块)

1. 开发调试

# 此为开始调试用,实际内部不做任何操作
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎
'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
'KEY_PREFIX': '', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
} # 自定义key
def default_key_func(key, key_prefix, version):
"""
Default function to generate keys. Constructs the key used by all other methods. By default it prepends
the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
function with custom key making behavior.
"""
return '%s:%s:%s' % (key_prefix, version, key) def get_key_func(key_func):
"""
Function to decide which key function to use. Defaults to ``default_key_func``.
"""
if key_func is not None:
if callable(key_func):
return key_func
else:
return import_string(key_func)
return default_key_func 

2. 内存

# 此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
} # 注:其他配置同开发调试版本

3. 文件

# 此缓存将内容保存至文件
# 配置: CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR,'cache'),
}
}
# 注:其他配置同开发调试版本

4. 数据库

# 此缓存将内容保存至数据库

    # 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 数据库表
}
} # 注:执行创建表命令 python manage.py createcachetable

5. Memcache缓存(python-memcached模块)

# 此缓存使用python-memcached模块连接memcache

    CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

6. Memcache缓存(pylibmc模块)

# 此缓存使用pylibmc模块连接memcache

    CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
} CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

应用

1. 全站使用缓存

使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

    MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',#放到第一个中间件位置,只有pcocess_response()
# 其他中间件...
'django.middleware.cache.FetchFromCacheMiddleware',#放到最后一个只,有pcocess_request()
] CACHE_MIDDLEWARE_ALIAS = ""
CACHE_MIDDLEWARE_SECONDS = ""
CACHE_MIDDLEWARE_KEY_PREFIX = ""

2. 单独视图缓存

方式一:
from django.views.decorators.cache import cache_page @cache_page(60 * 15)
def my_view(request):
... 方式二:
from django.views.decorators.cache import cache_page urlpatterns = [
url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]

案例

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR,'cache'),
}
}

project/settings.py #使用文件缓存方式

from django.views.decorators.cache import cache_page

@cache_page(5) #5秒失效,默认300秒
def cache(request):
import time
ctime = time.time()
return render(request,'cache.html',{'ctime': ctime})

app01/views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ ctime }}</h1>
<h1>{{ ctime }}</h1>
<h1>{{ ctime }}</h1>
</body>
</html>

templates/cache.html

3. 局部视图缓存

a. 引入TemplateTag

        {% load cache %}

    b. 使用缓存

        {% cache 5000 缓存key %}
缓存内容
{% endcache %}

案例

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR,'cache'),
}
}

project/settings.py #使用文件缓存方式

def cache(request):
import time
ctime = time.time()
return render(request,'cache.html',{'ctime': ctime})

app01/views.py

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ ctime }}</h1>
<h1>{{ ctime }}</h1> {% cache 5 key1 %} <!--局部视图,5秒失效-->
<h1>{{ ctime }}</h1>
{% endcache %}
</body>
</html>

templates/cache.html

信号

 描述:Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。

Django内置信号

Model signals
pre_init # django的modal执行其构造方法前,自动触发
post_init # django的modal执行其构造方法后,自动触发
pre_save # django的modal对象保存前,自动触发
post_save # django的modal对象保存后,自动触发
pre_delete # django的modal对象删除前,自动触发
post_delete # django的modal对象删除后,自动触发
m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
pre_migrate # 执行migrate命令前,自动触发
post_migrate # 执行migrate命令后,自动触发
Request/response signals
request_started # 请求到来前,自动触发
request_finished # 请求结束后,自动触发
got_request_exception # 请求异常后,自动触发
Test signals
setting_changed # 使用test测试修改配置文件时,自动触发
template_rendered # 使用test测试渲染模板时,自动触发
Database Wrappers
connection_created # 创建数据库连接时,自动触发

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate from django.test.signals import setting_changed
from django.test.signals import template_rendered from django.db.backends.signals import connection_created def callback(sender, **kwargs):
print("xxoo_callback")
print(sender,kwargs) xxoo.connect(callback)
# xxoo指上述导入的内容
from django.core.signals import request_finished
from django.dispatch import receiver @receiver(request_finished)
def my_callback(sender, **kwargs):
print("Request finished!")

自定义信号

a. 定义信号

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

b. 注册信号

def callback(sender, **kwargs):
print("callback")
print(sender,kwargs) pizza_done.connect(callback)

c. 触发信号

from 路径 import pizza_done

pizza_done.send(sender='seven',toppings=123, size=456)

由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。

内置信号案例:

from django.db.models.signals import pre_init, post_init   #举例

def f1(sender, **kwargs):
print("f1_callback")
# print(sender,kwargs)
pre_init.connect(f1) #django的modal执行其构造方法前,自动触发 def f2(sender, **kwargs):
print("f2_callback")
# print(sender,kwargs)
post_init.connect(f2) #django的modal执行其构造方法后,自动触发

sg.py #新建文件

import sg   

project/_init_.py

from django.db import models

# Create your models here.

class Userinfo(models.Model):
user = models.CharField(max_length=64)

app01/models.py

urlpatterns = [
url(r'^sg/$',views.sg),
]

project/urls.py

def sg(requset):
from app01 import models obj = models.Userinfo(user='root1')
print('start')
obj.save() obj = models.Userinfo(user='root2')
obj.save() obj = models.Userinfo(user='root3')
obj.save()
return HttpResponse('OK!')

app01/views.py

打印结果

f1_callback
f2_callback
start
f1_callback
f2_callback
f1_callback
f2_callback

自定义信号:

#自定义信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"]) def callback(sender, **kwargs):
print("callback")
print(sender, kwargs)
pizza_done.connect(callback)

sg.py

def sg(requset):
from app01 import models obj = models.Userinfo(user='root1')
print('start')
obj.save() obj = models.Userinfo(user='root2')
obj.save() obj = models.Userinfo(user='root3')
obj.save() #自定义信号
from sg import pizza_done
pizza_done.send(sender='seven', toppings=123, size=456)
return HttpResponse('OK!')

app01/views.py

打印结果

f1_callback
f2_callback
start
f1_callback
f2_callback
f1_callback
f2_callback
callback
seven {'signal': <django.dispatch.dispatcher.Signal object at 0x0000020D7C6DB668>, 'toppings': 123, 'size': 456}

  

【Django】中间件,csrf,缓存,信号的更多相关文章

  1. 【python】-- Django 中间件、缓存、信号

    Django  中间件.缓存.信号 一. Django  中间件 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的 ...

  2. day20 FORM补充(随时更新),F/Q操作,model之多对多,django中间件,缓存,信号

    python-day20 1.FROM生成select标签的数据应该来源于数据库. 2.model 操作 F/Q  (组合查询) 3.model 多对多操作. 4.中间件 :在请求到达url前先会经过 ...

  3. $Django 中间件 csrf

     中间件  -中间件是什么?请求和响应之间的一道屏障  -中间件作用:控制请求和响应  -django中内置几个中间件   process_request(self,request)   proces ...

  4. django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块

    CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...

  5. django中间件 csrf auth认证

    django中间件 能做全局访问频率限制,身份校验,黑名单,白名单 用法: 新建一个文件夹,文件夹新建一个py文件,文件中写如下代码 注意点:你写的类必须继续MiddlewareMixin from ...

  6. Django——中间件设置缓存

    如图所示查看网站缓存时间 在app中创建middleware.py文件,导入MiddlewareMixin,创建类并继承MiddlewareMixin 在settings中的MIDDLEWARE=[ ...

  7. Web框架之Django_09 重要组件(Django中间件、csrf跨站请求伪造)

    摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于 ...

  8. Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)

    Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造)   摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...

  9. Python之路-(Django(csrf,中间件,缓存,信号,Model操作,Form操作))

    csrf 中间件 缓存 信号 Model操作 Form操作 csrf: 用 django 有多久,我跟 csrf 这个概念打交道就有久了. 每次初始化一个项目时都能看到 django.middlewa ...

  10. Django 五——中间件、缓存、CSRF、信号、Bootstrap(模板)

    内容概要: 1.Django的请求生命周期是怎么样的? 2.中间件 3.CSRF补充 4.信号 5.Bootstrap(模板) 1.Django的请求生命周期是怎么样的? (即请求发起到返回都经历了什 ...

随机推荐

  1. python 35 多线程

    目录 多线程 1. 线程 2. 线程vs进程 3. 开启线程的两种方法. 4. 线程的特性 5. 线程的相关方法 6. join 阻塞 7. 守护线程 daemon 8. 互斥锁 多线程 1. 线程 ...

  2. 对IOC和DI的通俗理解

    学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  3. Codeforces 246C

    题意略. 思路: 我们将数组中的数字从大到小排列,分别考虑取前0 + 1,1 + 1,2 + 1.....个的情况. 所谓i + 1的意思是,取前i个的时候,同时取第[i + 1],[i + 2],. ...

  4. jQuery事件以及动画

    jQuery事件以及动画 一.jQuery事件 加载DOM 在页面加载完毕后, 浏览器会通过 JavaScript 为 DOM 元素添加事件. 在常规的 JavaScript 代码中, 通常使用 wi ...

  5. ‎CocosBuilder 学习笔记(2) .ccbi 文件结构分析

    ccbi总体结构 CCBReader按字节读取.ccbi内容,每个字节8位二进制. .ccbi总体结构分为4个部分: Header 第0-3字节:ibcc .ccbi文件的标志.readHeader方 ...

  6. 从零开始搭建Java开发环境第三篇:最新版IDEA常用配置指南,打造你的最酷IDE

    刚刚使用IntelliJ IDEA 编辑器的时候,会有很多设置,会方便以后的开发,工欲善其事必先利其器. 比如:设置文件字体大小,代码自动完成提示,版本管理,本地代码历史,自动导入包,修改注释,修改t ...

  7. Linux下Tomcat项目访问路径修改

    1.去除端口号8080. 首先,进入tomcat的安装目录下的conf目录,我的目录是 /usr/local/apache-tomcat-9.0.20/conf,编辑文件server.xml. 将se ...

  8. TK图形界面

    import tkinter 1.使用tkinter模块前 一般先要建立一个tkinter的对象     例: window = tkinter.TK()   2.建立完对象设置好窗口属性以及所有功能 ...

  9. CFdiv2 165E. Compatible Numbers 子集枚举

    传送门 题意: 给出一个序列,输出每个数x对应的一个ans,要求ans在数列中,并且ans & x  = 0:数列的每个数小于(4e6) 思路: 这道题的方向比较难想.想到了就比较轻松了,可以 ...

  10. Codeforces Round #486 (Div. 3)988E. Divisibility by 25技巧暴力||更暴力的分类

    传送门 题意:给定一个数,可以对其做交换相邻两个数字的操作.问最少要操作几步,使得可以被25整除. 思路:问题可以转化为,要做几次交换,使得末尾两个数为00或25,50,75: 自己一开始就是先for ...